Texture loading

Started by
4 comments, last by cifa 10 years, 11 months ago

Hi there,

First of all sorry for the noobish question. I just want to render a model with a texture. Without the usage of texture everything works fine, it I use a texture nothing shows up.

Here's the relevant code:

In initBuffers


	glGenBuffers(1, &vertexTextureCoordBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertexTextureCoordBuffer);

	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*loadedModel.textures.size(), &(loadedModel.positions[0]), GL_STATIC_DRAW);
	vertexTextField.itemSize=2;
	vertexTextField.numItems=loadedModel.textures.size() / 2;

Then somewhere


	GLuint tex=loadBMP_custom("mypath\green.bmp");

Then in drawScene


		glActiveTexture( GL_TEXTURE0 );
		glBindTexture(GL_TEXTURE_2D, tex);
		glUniform1i(program.samplerUniform, 0);

		glBindBuffer(GL_ARRAY_BUFFER, vertexTextureCoordBuffer);
		glVertexAttribPointer(
			program.textureCoordAttribute,
			vertexTextField.itemSize,
			GL_FLOAT,
			GL_FALSE,
			0,
			(void*)0
			);

Whereas load_BMP is something found on opegl-tutorials.com and here it is:



GLuint loadBMP_custom(const char * imagepath){

	printf("Reading image %s\n", imagepath);

	// Data read from the header of the BMP file
	unsigned char header[54];
	unsigned int dataPos;
	unsigned int imageSize;
	unsigned int width, height;
	// Actual RGB data
	unsigned char * data;

	// Open the file
	FILE * file = fopen(imagepath,"rb");
	if (!file)							    {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); return 0;}

	// Read the header, i.e. the 54 first bytes

	// If less than 54 byes are read, problem
	if ( fread(header, 1, 54, file)!=54 ){ 
		printf("Not a correct BMP file\n");
		return 0;
	}
	// A BMP files always begins with "BM"
	if ( header[0]!='B' || header[1]!='M' ){
		printf("Not a correct BMP file\n");
		return 0;
	}
	// Make sure this is a 24bpp file
	if ( *(int*)&(header[0x1E])!=0  )         {printf("Not a correct BMP file\n");    return 0;}
	if ( *(int*)&(header[0x1C])!=24 )         {printf("Not a correct BMP file\n");    return 0;}

	// Read the information about the image
	dataPos    = *(int*)&(header[0x0A]);
	imageSize  = *(int*)&(header[0x22]);
	width      = *(int*)&(header[0x12]);
	height     = *(int*)&(header[0x16]);

	// Some BMP files are misformatted, guess missing information
	if (imageSize==0)    imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
	if (dataPos==0)      dataPos=54; // The BMP header is done that way

	// Create a buffer
	data = new unsigned char [imageSize];

	// Read the actual data from the file into the buffer
	fread(data,1,imageSize,file);

	// Everything is in memory now, the file wan be closed
	fclose (file);

	// Create one OpenGL texture
	GLuint textureID;
	glGenTextures(1, &textureID);
	
	// "Bind" the newly created texture : all future texture functions will modify this texture
	glBindTexture(GL_TEXTURE_2D, textureID);

	// Give the image to OpenGL
	glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);

	// OpenGL has now copied the data. Free our own version
	delete [] data;

	// Poor filtering, or ...
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

	// ... nice trilinear filtering.
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
	glGenerateMipmap(GL_TEXTURE_2D);

	// Return the ID of the texture we just created
	return textureID;
}

The shaders are: (I know that something is deprecated, but I need those things)




#version 330 core 

precision mediump float;

varying vec3 vTransformedNormal;
    varying vec2 vTextureCoord;

varying vec4 vPosition;

uniform vec3 uPointLightingLocation;
uniform vec3 uPointLightingDiffuseColor;
uniform vec3 uAmbientColor;
uniform vec3 uColor;

uniform sampler2D uSampler;

void main(void){
  
  vec3 lightWeighting;
  vec3 lightDirection = normalize(uPointLightingLocation - vPosition.xyz);
  vec3 normal = normalize(vTransformedNormal);
  float diffuseLightWeighting=max(dot(normal, lightDirection),0.0);
  lightWeighting=uAmbientColor+uPointLightingDiffuseColor*diffuseLightWeighting;

  vec4 fragmentColor=vec4(uColor.rgb,1.0);
  fragmentColor = texture(uSampler, vTextureCoord);
  gl_FragColor=vec4(fragmentColor.rgb*lightWeighting, fragmentColor.a);


}


#version 330 core 
 
attribute vec2 aTextureCoord;
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;

uniform mat3 uNMatrix;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;

varying vec4 vPosition;
varying vec3 vTransformedNormal;
varying vec2 vTextureCoord;


void main(void){
	vPosition=uMVMatrix*vec4(aVertexPosition, 1.0);
	vTransformedNormal=uNMatrix*aVertexNormal;
    vTextureCoord = aTextureCoord;

	gl_Position=uPMatrix*vPosition;
}

Thank you so much :D

Advertisement

i just wonder where is glEnable(GL_TEXUTRE_2D); ?

tell me if that works ;]

i just wonder where is glEnable(GL_TEXUTRE_2D); ?

tell me if that works ;]

Nope, not working :(

Thank you anyway

What do you mean with "nothing shows up"? Does stuff render on the screen if you replace the output color with red for example? I'd suggest to run your program with gDebugger, you can check with it that your texture is loaded correctly and shaders linked. And does that "mypath\green.bmp" really work? \ is used for escape sequences, so I'd suggest you to change it to /

Derp

i just wonder where is glEnable(GL_TEXUTRE_2D); ?

tell me if that works ;]

This is not used with shaders.

Some things you can try:

As Sponji said, this line is bad:


	GLuint tex=loadBMP_custom("mypath\green.bmp");

Instead of "mypath\green.bmp" use "mypath\\green.bmp" or "mypath/green.bmp" - the compiler will interpret "\g" as an escape sequence. The fact that you don't appear ro be error checking this is not a good sign; at the very least you should be checking that you are actually getting a non-zero return value from your loadBMP_custom function. I wonder what compiler you're using that you're not getting at least a warning from trying to use "\g"?

Reduce your fragment shader to an absolute minimum; i.e just a "gl_FragColor = texture(uSampler, vTextureCoord);" line. If this works then your texture loading is OK and the problem is in your lighting code. Note that I'm not recommending this as a solution - it's a testing/debugging step.

Check that your shaders have compiled and linked successfully.

Double-check your source bitmap image. Is it a power of two? Is it's width * bpp a multiple of 4? These are all things that can cause problems.

Sprinkle some "assert (glGetError () == GL_NO_ERROR);" calls at key points in your code - after texture loading, shader compilation, vertex setup, etc. Run in the debugger and ensure that everything works without internal GL errors.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

What do you mean with "nothing shows up"? Does stuff render on the screen if you replace the output color with red for example? I'd suggest to run your program with gDebugger, you can check with it that your texture is loaded correctly and shaders linked. And does that "mypath\green.bmp" really work? \ is used for escape sequences, so I'd suggest you to change it to /



Yup, if I switch program to one with a fragment shader that output a color, it works.
The path string is a not the real one, it is correct in code biggrin.png


i just wonder where is glEnable(GL_TEXUTRE_2D); ?

tell me if that works ;]


This is not used with shaders.

Some things you can try:

As Sponji said, this line is bad:
	GLuint tex=loadBMP_custom("mypath\green.bmp");

Instead of "mypath\green.bmp" use "mypath\\green.bmp" or "mypath/green.bmp" - the compiler will interpret "\g" as an escape sequence. The fact that you don't appear ro be error checking this is not a good sign; at the very least you should be checking that you are actually getting a non-zero return value from your loadBMP_custom function. I wonder what compiler you're using that you're not getting at least a warning from trying to use "\g"?

Reduce your fragment shader to an absolute minimum; i.e just a "gl_FragColor = texture(uSampler, vTextureCoord);" line. If this works then your texture loading is OK and the problem is in your lighting code. Note that I'm not recommending this as a solution - it's a testing/debugging step.

Check that your shaders have compiled and linked successfully.

Double-check your source bitmap image. Is it a power of two? Is it's width * bpp a multiple of 4? These are all things that can cause problems.

Sprinkle some "assert (glGetError () == GL_NO_ERROR);" calls at key points in your code - after texture loading, shader compilation, vertex setup, etc. Run in the debugger and ensure that everything works without internal GL errors.



As I told to Sponji, the path is not written that way in code.
The same shader without the texture stuff, works fine. I've a specular code with everything that's the same, except for the texture stuff, so I'm pretty sure that my problem is there.
Oh and the .bmp is fine!
I'll play around with assert now biggrin.png


Thank you both for your answer.



EDIT:

It appears that I'm a was a little to drowsy when I was writing my initShader function, I was searching for the texture coord attribute into the wrong program (I have 3 of them, one of those without texture).
Thank you for your support and I'm sorry for the lost of time biggrin.png

This topic is closed to new replies.

Advertisement