I need to repeatedly display an image–say, one frame from a video stream–on a monitor at 120hz. I think this is an issue of vsync. I’m wondering whether opengl can help to display an existing image or it can only draw animations and display them. If possible, could someone show me some codes as an example ? Thanks.
Of course you can
Here an example that display a picture image file into an resizable OpenGL window
#include <IL/il.h>
#include <GL/glut.h>
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480
int width = DEFAULT_WIDTH;
int height = DEFAULT_HEIGHT;
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display()
{
// Clear color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Operate on model-view matrix
/* Draw a quad */
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(0, 1); glVertex2i(0, height);
glTexCoord2i(1, 1); glVertex2i(width, height);
glTexCoord2i(1, 0); glVertex2i(width, 0);
glEnd();
glutSwapBuffers();
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei newwidth, GLsizei newheight)
{
// Set the viewport to cover the new window
glViewport(0, 0, width=newwidth, height=newheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
/* Initialize OpenGL Graphics */
void initGL(int w, int h)
{
glViewport(0, 0, w, h); // use a screen size of WIDTH x HEIGHT
glEnable(GL_TEXTURE_2D); // Enable 2D texturing
glMatrixMode(GL_PROJECTION); // Make a simple 2D projection on the entire window
glLoadIdentity();
glOrtho(0.0, w, h, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW); // Set the matrix mode to object modeling
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the window
}
/* Load an image using DevIL and return the devIL handle (-1 if failure) */
int LoadImage(char *filename)
{
ILboolean success;
ILuint image;
ilGenImages(1, &image); /* Generation of one image name */
ilBindImage(image); /* Binding of image name */
success = ilLoadImage(filename); /* Loading of the image filename by DevIL */
if (success) /* If no error occured: */
{
/* Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
if (!success)
{
return -1;
}
}
else
return -1;
return image;
}
int main(int argc, char **argv)
{
GLuint texid;
int image;
if ( argc < 1)
{
/* no image file to display */
return -1;
}
/* GLUT init */
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); // Set the window's initial width & height
glutCreateWindow(argv[0]); // Create window with the name of the executable
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
/* OpenGL 2D generic init */
initGL(DEFAULT_WIDTH, DEFAULT_HEIGHT);
/* Initialization of DevIL */
if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
printf("wrong DevIL version
");
return -1;
}
ilInit();
/* load the file picture with DevIL */
image = LoadImage(argv[1]);
if ( image == -1 )
{
printf("Can't load picture file %s by DevIL
", argv[1]);
return -1;
}
/* OpenGL texture binding of the image loaded by DevIL */
glGenTextures(1, &texid); /* Texture name generation */
glBindTexture(GL_TEXTURE_2D, texid); /* Binding of texture name */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */
/* Main loop */
glutMainLoop();
/* Delete used resources and quit */
ilDeleteImages(1, &image); /* Because we have already copied image data into texture data we can release memory used by image. */
glDeleteTextures(1, &texid);
return 0;
}
This compile using this on a linux box with have GL, GLUT and devIL development libraries :
gcc devil_example.c -lGL -lglut -lIL -o devil_example
Use this simple syntax for to display an graphic image file into a resizable OpenGL window
./devil_example your_image_file.jpg
(this work too with a lot of others graphics file formats than .jpg)
thank you so much. I tried your code with an image and it worked. But I need to read a video stream frame by frame, process the frames ( eliminate the noise, for example) and then display the frames at 120hz. I am wondering whether opengl can help to read video frames. Thanks!
Hi. I have a question. When drawing image file on the screen with openGL in C , Devil library or others libraries are used necessary or not?? Do you implement this code only openGL? There is a one thing…I need drawing image from file on the screen with openGL and C. Please help me
OpenGL does not contain functions to read files or interpret image file formats. You don’t have to use an image loading library, but then you have to write code to read and interpret the image file content yourself. How complex of a task that is depends a lot on the image format. Some are as simple as a few bytes of header information and then just a sequence of RGB values others use clever compression schemes and can store data in a large variety of ways. It is usually much simpler to use a library that can read a variety of image formats through the same API and not worry about the specific file formats (and their idiosyncrasies) - it also makes your program more flexible, because it is not tied to a very specific file format.