Sign in to follow this  

OpenGL Using DevIL

This topic is 3735 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm tryng to use DevIL to load an image so I can use it as a texture in my openGL program. I've tried to implement the code from this wiki site into my C/openGL/GLUT code but I cant get it to work. I realise that the site uses SDL but I think I've stripped out the DevIL code I need. I've basically just plonked it all into a seperate function and then called that from my display function. When I run it the window appears but it's empty (not black background - I can see my desktop/windows etc inside the window). As you can probably tell I'm a bit of a newcomer to all this so any advice would be much appreciated, as would any pointers to some DevIL tutorial guides because this wiki is all I can find that covers the basic code - however it doesn't really explain any of the code which is probably why I'm struggling. Here's my code:
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <IL/il.h>
#include <IL/ilu.h>
#include <IL/ilut.h>
//#include <IL/ilu_region.h>
#include "IL/devil_internal_exports.h"



ILuint texid; //ILuint is a 32bit unsigned integer. Variable texid will be used to store image name. 
ILboolean success;
GLuint image;	
int finished;

float xpos = 0.0, ypos = 0.0, zpos = 5.0, xrot = 0, yrot = 0, zrot =0,  angle=0.0, ratio;


void loadImage(){

	glViewport(0, 0, 256, 256);
	glEnable(GL_TEXTURE_2D);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 256.0, 256.0, 0.0, 0.0, 100.0);
	glMatrixMode(GL_MODELVIEW);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	
	ilInit();
	ilGenImages(1, &texid); // Generation of one image name 
	ilBindImage(texid); // Binding of image name 
	
	success = ilLoadImage((const ILstring)"E:\image.jpg"); // Loading of image "image.jpg" 

	if (success){ // If no error occured: 
		success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); // Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA 
		if (!success){
			printf("error");
			exit(0);
		}
    
		glGenTextures(1, &image); // Texture name generation 
		glBindTexture(GL_TEXTURE_2D, image); // 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 
		}
	else {
		printf("error2");
		exit(0);
	}
  
	ilDeleteImages(1, &texid); // Because we have already copied image data into texture data we can release memory used by image. 	

	glBegin(GL_QUADS);
    glTexCoord2i(0, 0); glVertex2i(0, 0);
    glTexCoord2i(0, 1); glVertex2i(0, 256);
    glTexCoord2i(1, 1); glVertex2i(256, 256);
    glTexCoord2i(1, 0); glVertex2i(256, 0);
    glEnd();
	
	glDeleteTextures(1, &image);
}



void init(){
	
	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
}


void reshape( int w, int h )
{
	if(h == 0) //
		h = 1;

	ratio = 1.0f * w / h;
	// Reset the coordinate system before modifying
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// Set the viewport to be the entire window
    glViewport(0, 0, w, h);

	// Set the clipping volume
	gluPerspective(80,ratio,1,200);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0, 0, 30,
		      0,0,10,
			  0.0f,1.0f,0.0f);
}

void camera (void) {
	
	glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on the x-axis (left and right)
	glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
	glRotatef(zrot,0.0,0.0,1.0); 
}


void display( void )
{
	camera();
	loadImage();
}



void keyboard (unsigned char key, int x, int y) {
	
	//Rotate about X axis
	if (key=='q') {
		xrot += 10;
		if (xrot >360) xrot -= 360; 
	}
	if (key=='z'){
		xrot -= 10;
		if (xrot < -360) xrot += 360;
	}
	
	//Rotate about Y axis
	if (key=='d'){
		yrot += 10;
		if (yrot >360) yrot -= 360;
	}
	if (key=='a'){
		yrot -= 10;
		if (yrot < -360)yrot += 360;
	}

	//Rotate about Z axis
	if (key=='e'){
		zrot += 10;
		if (zrot >360) zrot -= 360;
	}
	if (key=='c'){
		zrot -= 10;
		if (zrot < -360)zrot += 360;
	}

	if (key==27){
		exit(0);
	}
}


int main (int argc, char **argv)
{

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
	glutInitWindowSize(550, 550);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Testing");
	init();
	glutDisplayFunc(display);
	glutIdleFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	glutMainLoop();

	return 0;
}


Thanks again.

Share this post


Link to post
Share on other sites
First of all I must say that I haven't used DevIL so I can't really comment on that one.But what I have to say is that you are generating the image every frame in your display callback which is bad and slow.Also you are setting every frame your projection view which is not required either.You can put them in your init code and draw everyhing else in the draw call.Also you have to use glBindTexture before glBegin to set the current texture when you want to render it.These are just of the top of my head,someone else may show you other errors as well.

Share this post


Link to post
Share on other sites
Does the image has power of 2 dimensions? if now, are you sure your card supports the NPOT extension?

The call to ilInit() should be in your main() function rather than loadImage() but I doubt that would cause it to fail.

Share this post


Link to post
Share on other sites
Thanks mrbastard, it was the glutSwapBuffers. So I've put those in and tried to alter the data a bit by putting more in init() and less in display(). It now displays the texture on screen but I cant use gluLookAt() or it disappears, and when I use any of my camera functions the image doesn't redraw, I can see the top of the texture flickering but the rest is black - it's almost as if it cant redraw it quick enough - but I dont think this is the probably because my computer's pretty fast (C2D @2.9GHz, 7800GTX). I think it's more to do with the fact I've got code in the wrong place, is there anywhere that explains where these functions should be placed in your call?

Here's my new code:

   
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <IL/il.h>
#include <IL/ilu.h>
#include <IL/ilut.h>
//#include <IL/ilu_region.h>
#include "IL/devil_internal_exports.h"



ILuint texid; //ILuint is a 32bit unsigned integer. Variable texid will be used to store image name.
ILboolean success;
GLuint image;
int finished;

float xpos = 0.0, ypos = 0.0, zpos = 5.0, xrot = 0, yrot = 0, zrot =0, angle=0.0, ratio;


void loadImage(){

glViewport(0, 0, 256, 256);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 256.0, 256.0, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//gluLookAt(0, 0, 10, 0,0,1,0.0f,1.0f,0.0f);

glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(0, 1); glVertex2i(0, 256);
glTexCoord2i(1, 1); glVertex2i(256, 256);
glTexCoord2i(1, 0); glVertex2i(256, 0);
glEnd();

glutSwapBuffers();
//glDeleteTextures(1, &image);

}



void init(){

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

ilInit();
ilGenImages(1, &texid); // Generation of one image name
ilBindImage(texid); // Binding of image name

success = ilLoadImage((const ILstring)"E:\image.jpg"); // Loading of image "image.jpg"

if (success){ // If no error occured:
success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); // Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA
if (!success){
printf("error");
exit(0);
}

glGenTextures(1, &image); // Texture name generation
glBindTexture(GL_TEXTURE_2D, image); // 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
}
else {
printf("error2");
exit(0);
}

ilDeleteImages(1, &texid); // Because we have already copied image data into texture data we can release memory used by image.

}


void reshape( int w, int h )
{
if(h == 0) //
h = 1;

ratio = 1.0f * w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Set the clipping volume
gluPerspective(80,ratio,1,200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0, 0, 10, 0,0,1, 0.0f,1.0f,0.0f);
}

void camera (void) {

glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on the x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glRotatef(zrot,0.0,0.0,1.0);
}


void display( void )
{
camera();
loadImage();
}



void keyboard (unsigned char key, int x, int y) {

//Rotate about X axis
if (key=='q') {
xrot += 10;
printf("qq");
if (xrot >360) xrot -= 360;
}
if (key=='z'){
xrot -= 10;
if (xrot < -360) xrot += 360;
}

//Rotate about Y axis
if (key=='d'){
yrot += 10;
if (yrot >360) yrot -= 360;
}
if (key=='a'){
yrot -= 10;
if (yrot < -360)yrot += 360;
}

//Rotate about Z axis
if (key=='e'){
zrot += 10;
if (zrot >360) zrot -= 360;
}
if (key=='c'){
zrot -= 10;
if (zrot < -360)zrot += 360;
}

if (key==27){
exit(0);
}
}


int main (int argc, char **argv)
{

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
glutInitWindowSize(550, 550);
glutInitWindowPosition(100, 100);
glutCreateWindow("Testing");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();

return 0;
}




Thanks again.

Share this post


Link to post
Share on other sites
Why do you want to use gluLookAt with a orthographic projection ?Also move this code out of loadImage and at your init or in separate function called setOrtho

glViewport(0, 0, 256, 256);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 256.0, 256.0, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);

You only need to reset the view by calling glLoadIdentity() at the start of your display callback,but in this case you are not required to set the Projection matrix every frame(it's only required if you want to mix 2d and 3d in the scene)

Share this post


Link to post
Share on other sites
Quote:
Original post by mpledge52
Thanks mrbastard

No problem.
Quote:
Original post by mpledge52
it's almost as if it cant redraw it quick enough - but I dont think this is the probably because my computer's pretty fast (C2D @2.9GHz, 7800GTX).

It's because you're loading the image every frame.

There's nothing that will tell you exactly where to call anything - after all nobody knows where to call it in your code except you. In general though, it sounds like you need to get used to following the flow of your program in your mind. Though some of your problems may be down to misunderstanding glut.

For example, the function pointer passed to glutDisplay will be called every frame. In your case this means every instruction in display() gets called every frame, which in turn means loadImage gets called every frame. This why it can't redraw quick enough - it doesn't matter how fast your cpu and gpu are if they have to wait for the image file to load from disk EVERY FRAME before they can do their work. Make sense?

So, I suggest seperating out your drawing and image loading / texture upload code.

Share this post


Link to post
Share on other sites
Thanks everyone its working perfectly now. [smile]

Is there any way I can copy the texture image into a 2D array so I can view/manipulate the data stored in it?

Share this post


Link to post
Share on other sites
Quote:
Original post by mpledge52
Is there any way I can copy the texture image into a 2D array so I can view/manipulate the data stored in it?

You can allocate an array in your application which has the same size of the original image, then copy the image data to your array using memcpy() of C/C++ or ilCopyPixels() of DevIL.

int dataSize = width * height * 3; // 3 bytes per pixel (RGB)
unsigned char* buffer = new unsigned char[dataSize];
memcpy(buffer, ilGetData(), dataSize);
// or use DevIL function
ilCopyPixels(0,0, width, height, 1, IL_RGB, IL_BYTE, (void*)buffer);
...
delete [] buffer;



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Similar Content

    • By xhcao
      Does sync be needed to read texture content after access texture image in compute shader?
      My simple code is as below,
      glUseProgram(program.get());
      glBindImageTexture(0, texture[0], 0, GL_FALSE, 3, GL_READ_ONLY, GL_R32UI);
      glBindImageTexture(1, texture[1], 0, GL_FALSE, 4, GL_WRITE_ONLY, GL_R32UI);
      glDispatchCompute(1, 1, 1);
      // Does sync be needed here?
      glUseProgram(0);
      glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
      glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                     GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture[1], 0);
      glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
       
      Compute shader is very simple, imageLoad content from texture[0], and imageStore content to texture[1]. Does need to sync after dispatchCompute?
    • By Jonathan2006
      My question: is it possible to transform multiple angular velocities so that they can be reinserted as one? My research is below:
      // This works quat quaternion1 = GEQuaternionFromAngleRadians(angleRadiansVector1); quat quaternion2 = GEMultiplyQuaternions(quaternion1, GEQuaternionFromAngleRadians(angleRadiansVector2)); quat quaternion3 = GEMultiplyQuaternions(quaternion2, GEQuaternionFromAngleRadians(angleRadiansVector3)); glMultMatrixf(GEMat4FromQuaternion(quaternion3).array); // The first two work fine but not the third. Why? quat quaternion1 = GEQuaternionFromAngleRadians(angleRadiansVector1); vec3 vector1 = GETransformQuaternionAndVector(quaternion1, angularVelocity1); quat quaternion2 = GEQuaternionFromAngleRadians(angleRadiansVector2); vec3 vector2 = GETransformQuaternionAndVector(quaternion2, angularVelocity2); // This doesn't work //quat quaternion3 = GEQuaternionFromAngleRadians(angleRadiansVector3); //vec3 vector3 = GETransformQuaternionAndVector(quaternion3, angularVelocity3); vec3 angleVelocity = GEAddVectors(vector1, vector2); // Does not work: vec3 angleVelocity = GEAddVectors(vector1, GEAddVectors(vector2, vector3)); static vec3 angleRadiansVector; vec3 angularAcceleration = GESetVector(0.0, 0.0, 0.0); // Sending it through one angular velocity later in my motion engine angleVelocity = GEAddVectors(angleVelocity, GEMultiplyVectorAndScalar(angularAcceleration, timeStep)); angleRadiansVector = GEAddVectors(angleRadiansVector, GEMultiplyVectorAndScalar(angleVelocity, timeStep)); glMultMatrixf(GEMat4FromEulerAngle(angleRadiansVector).array); Also how do I combine multiple angularAcceleration variables? Is there an easier way to transform the angular values?
    • By dpadam450
      I have this code below in both my vertex and fragment shader, however when I request glGetUniformLocation("Lights[0].diffuse") or "Lights[0].attenuation", it returns -1. It will only give me a valid uniform location if I actually use the diffuse/attenuation variables in the VERTEX shader. Because I use position in the vertex shader, it always returns a valid uniform location. I've read that I can share uniforms across both vertex and fragment, but I'm confused what this is even compiling to if this is the case.
       
      #define NUM_LIGHTS 2
      struct Light
      {
          vec3 position;
          vec3 diffuse;
          float attenuation;
      };
      uniform Light Lights[NUM_LIGHTS];
       
       
    • By pr033r
      Hello,
      I have a Bachelor project on topic "Implenet 3D Boid's algorithm in OpenGL". All OpenGL issues works fine for me, all rendering etc. But when I started implement the boid's algorithm it was getting worse and worse. I read article (http://natureofcode.com/book/chapter-6-autonomous-agents/) inspirate from another code (here: https://github.com/jyanar/Boids/tree/master/src) but it still doesn't work like in tutorials and videos. For example the main problem: when I apply Cohesion (one of three main laws of boids) it makes some "cycling knot". Second, when some flock touch to another it scary change the coordination or respawn in origin (x: 0, y:0. z:0). Just some streng things. 
      I followed many tutorials, change a try everything but it isn't so smooth, without lags like in another videos. I really need your help. 
      My code (optimalizing branch): https://github.com/pr033r/BachelorProject/tree/Optimalizing
      Exe file (if you want to look) and models folder (for those who will download the sources):
      http://leteckaposta.cz/367190436
      Thanks for any help...

    • By Andrija
      I am currently trying to implement shadow mapping into my project , but although i can render my depth map to the screen and it looks okay , when i sample it with shadowCoords there is no shadow.
      Here is my light space matrix calculation
      mat4x4 lightViewMatrix; vec3 sun_pos = {SUN_OFFSET * the_sun->direction[0], SUN_OFFSET * the_sun->direction[1], SUN_OFFSET * the_sun->direction[2]}; mat4x4_look_at(lightViewMatrix,sun_pos,player->pos,up); mat4x4_mul(lightSpaceMatrix,lightProjMatrix,lightViewMatrix); I will tweak the values for the size and frustum of the shadow map, but for now i just want to draw shadows around the player position
      the_sun->direction is a normalized vector so i multiply it by a constant to get the position.
      player->pos is the camera position in world space
      the light projection matrix is calculated like this:
      mat4x4_ortho(lightProjMatrix,-SHADOW_FAR,SHADOW_FAR,-SHADOW_FAR,SHADOW_FAR,NEAR,SHADOW_FAR); Shadow vertex shader:
      uniform mat4 light_space_matrix; void main() { gl_Position = light_space_matrix * transfMatrix * vec4(position, 1.0f); } Shadow fragment shader:
      out float fragDepth; void main() { fragDepth = gl_FragCoord.z; } I am using deferred rendering so i have all my world positions in the g_positions buffer
      My shadow calculation in the deferred fragment shader:
      float get_shadow_fac(vec4 light_space_pos) { vec3 shadow_coords = light_space_pos.xyz / light_space_pos.w; shadow_coords = shadow_coords * 0.5 + 0.5; float closest_depth = texture(shadow_map, shadow_coords.xy).r; float current_depth = shadow_coords.z; float shadow_fac = 1.0; if(closest_depth < current_depth) shadow_fac = 0.5; return shadow_fac; } I call the function like this:
      get_shadow_fac(light_space_matrix * vec4(position,1.0)); Where position is the value i got from sampling the g_position buffer
      Here is my depth texture (i know it will produce low quality shadows but i just want to get it working for now):
      sorry because of the compression , the black smudges are trees ... https://i.stack.imgur.com/T43aK.jpg
      EDIT: Depth texture attachment:
      glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT24,fbo->width,fbo->height,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo->depthTexture, 0);
  • Popular Now