Texture not mapping properly

Apologies for the massive code dump here but I’m trying to make sure that I’ve provided enough information to help you all understand what I’m doing (which is) trying to get a grip on this new open GL 4.0 thing with the fancy shaders.

I’m pretty sure I’m making a rookie mistake of some kind here but I’ve spent all day with google going through tutorials and most of them are obsolete and the rest seem to just replicate what I’ve done.

Here is how I’m going about it:

  • init();
  • loadTextureLibrary();
  • loadShaderLibrary();
  • loadBufferLibrary();

Then the engine calls drawFrame() unto infinity.


void graphicsEngine::initialise(int argc, char* argv[])
{  
	glutInit(&argc, argv);

	glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
	glutCreateWindow("Enclave");

	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

	glutInitContextVersion(4, 1); // set version of gl to 4.1
	glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); // do not allow deprecated
	glutInitContextProfile(GLUT_CORE_PROFILE); // force current version of spec

	glewInit();

	glutDisplayFunc(drawFrame);
	glVersion();

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

	loadTextureLibrary();
	loadShaderLibrary();
	loadBufferLibrary();

	return;
}


void loadTextureLibrary()
{
	glGenSamplers(1 , &samplers[SAMPLER_TILE]);

	glSamplerParameteri(samplers[SAMPLER_TILE], GL_TEXTURE_MIN_FILTER , GL_NEAREST);  
	glSamplerParameteri(samplers[SAMPLER_TILE], GL_TEXTURE_MAG_FILTER , GL_NEAREST);  

	loadTexture(TEXTURE_GRASS, "code/textures/grass.tga");

}

void loadTexture(textureName type, char *texturePath)
{
	GLuint tex;
	TGAFILE f;

	LoadTGAFile(texturePath, &f);	

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, f.imageWidth, f.imageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, f.imageData);
	glGenerateMipmap(GL_TEXTURE_2D);  
    
	if (GLenum x = glGetError() != GL_NO_ERROR)
	{
		fprintf( stderr, "Texture did not load.
");
		return;
	}
	
	textures[type] = tex;
	return;
}


void loadShaderLibrary()
{
		//Load Shader
		loadShader(SHADER_TILE, "code/shaders/tile.vsh", "code/shaders/tile.fsh");

		if (GLenum x = glGetError() != GL_NO_ERROR)
		{
			fprintf( stderr, "Failed to load shader.
");
			return;
		}

		return;
}

void loadShader(shaderName programName, char *vertexPath, char *fragmentPath )
{
	const GLchar *vBuffer, *fBuffer;
	GLuint vx, fx;
	int ok;

	//Read shaders from disk.
	vBuffer = (GLchar *) enclave::readFile(vertexPath);
	fBuffer = (GLchar *) enclave::readFile(fragmentPath);

	vx = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vx, 1, &vBuffer, NULL);
	glCompileShader(vx);

	glGetShaderiv(vx, GL_COMPILE_STATUS, &ok);

	if (GLenum x = glGetError() != GL_NO_ERROR)
	{
		fprintf( stderr, "Shader vx did not compile.
");
		show_info_log(vx, glGetShaderiv, glGetShaderInfoLog);
		return;
	}
	
	fx = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fx, 1, &fBuffer, NULL);
	glCompileShader(fx);

	glGetShaderiv(fx, GL_COMPILE_STATUS, &ok);

	if (GLenum x = glGetError() != GL_NO_ERROR)
	{
		fprintf( stderr, "Shader fx did not compile.
");
		show_info_log(fx, glGetShaderiv, glGetShaderInfoLog);
		return;
	}
	 
	shaders[programName] = glCreateProgram();   

	glAttachShader(shaders[programName], vx);
        glAttachShader(shaders[programName], fx);
	glLinkProgram(shaders[programName]);
    
	glGetProgramiv(shaders[programName], GL_LINK_STATUS, &ok);
    

	glUseProgram(shaders[programName]);

	//Get Attributes
	glBindAttribLocation(shaders[SHADER_TILE], ATTRIB_VERTEX, "posIn");
	glBindAttribLocation(shaders[SHADER_TILE], ATTRIB_TEXCOORD, "texIn");	

        //Get uniforms.
	uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(shaders[SHADER_TILE], "texImage");

	glGetProgramiv(shaders[programName], GL_LINK_STATUS, &ok);
    
    if (!ok) {
		fprintf(stderr, "Failed to link shader program: %s, %s
", vertexPath, fragmentPath);
    }

	delete[] vBuffer;
	delete[] fBuffer;
	return; 
}


void loadBufferLibrary(void)
{

	static const GLfloat g_vertex_buffer_data[] = { 
			//Zero squares - ah ah ah.
			0.0f, 0.0f, 0.0f, 
			4.0f, 0.0f, 0.0f,
			0.0f, 4.0f, 0.0f,
			4.0f, 4.0f, 0.0f,
};


	static const GLfloat g_texture_buffer_data[] = { 
		0.0f, 0.0f,
		1.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,

	};

	generateBuffer(BUFFER_VERTEX, GL_ARRAY_BUFFER,  g_vertex_buffer_data, sizeof(g_vertex_buffer_data));
	generateBuffer(BUFFER_TEXCOORD, GL_ARRAY_BUFFER, g_texture_buffer_data, sizeof(g_texture_buffer_data));

	if (glGetError() != GL_NO_ERROR)
		fprintf(stderr,"Generate Buffer Error");

	return;
}

void generateBuffer( bufferName bName, GLenum target, const void *bufferData, GLsizei bufferSize ) {
    
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(target, buffer);
    glBufferData(target, bufferSize, bufferData, GL_STATIC_DRAW);
    buffers[bName] = buffer;
}


void drawFrame()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  
	//Set program and variables
        glUseProgram(shaders[SHADER_TILE]);

	glBindBuffer(GL_ARRAY_BUFFER, buffers[BUFFER_VERTEX]);
        glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray(ATTRIB_VERTEX);
  
	glBindBuffer(GL_ARRAY_BUFFER, buffers[BUFFER_TEXCOORD]);
        glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_TRUE, 0, NULL);
        glEnableVertexAttribArray(ATTRIB_TEXCOORD);
 
	glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_DIRT]);
	glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
	glBindSampler(0, samplers[SAMPLER_TILE]); 


	glActiveTexture(GL_TEXTURE0);
	glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
	glBindSampler(0, samplers[SAMPLER_TILE]); 

        glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_GRASS]);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4 );

	if (GLenum x = glGetError() != GL_NO_ERROR)
	{
		fprintf( stderr, "Rendering Error: %d
", x);
		return;
	}

	glDisableVertexAttribArray(ATTRIB_VERTEX);
	glDisableVertexAttribArray(ATTRIB_TEXCOORD);

	glFinish();

	glutSwapBuffers(); 
	//glutPostRedisplay();
	
}


void drawFrame()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  
	//Set program and variables
        glUseProgram(shaders[SHADER_TILE]);

	glBindBuffer(GL_ARRAY_BUFFER, buffers[BUFFER_VERTEX]);
        glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray(ATTRIB_VERTEX);

	glBindBuffer(GL_ARRAY_BUFFER, buffers[BUFFER_TEXCOORD]);
        glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_TRUE, 0, NULL);
        glEnableVertexAttribArray(ATTRIB_TEXCOORD);

	glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_DIRT]);
	glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
	glBindSampler(0, samplers[SAMPLER_TILE]); 


	glActiveTexture(GL_TEXTURE0);
	glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
	glBindSampler(0, samplers[SAMPLER_TILE]); 

        glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_GRASS]);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4 );

	if (GLenum x = glGetError() != GL_NO_ERROR)
	{
		fprintf( stderr, "Rendering Error: %d
", x);
		return;
	}

	glDisableVertexAttribArray(ATTRIB_VERTEX);
	glDisableVertexAttribArray(ATTRIB_TEXCOORD);

	glFinish();

	glutSwapBuffers(); 
	glutPostRedisplay();
	
}

Vertex shader:


#version 420
layout (location = 0) in vec3 posIn;
layout (location = 1) in vec2 texIn;

out vec2 texOut;

 mat4 scale(in float x, in float y, in float z)
{
    return mat4(
        vec4(x, 0.0, 0.0, 0.0),
        vec4(0.0, y, 0.0, 0.0),
        vec4(0.0, 0.0, z, 0.0),
        vec4(0.0, 0.0, 0.0, 1.0)
    );
}

mat4 translate(in float x, in float y, in float z)
{
    return mat4(
        vec4(1.0, 0.0, 0.0, 0.0),
        vec4(0.0, 1.0, 0.0, 0.0),
        vec4(0.0, 0.0, 1.0, 0.0),
        vec4(x, y, z, 1.0)
    );
}

void main()
{
	gl_Position = scale(2.0, 2.0, 1.0) * translate(0.0, 0.0, 0.0) * vec4(posIn, 1.0f);
	texOut = texIn;
}

Fragment Shader:


#version 420

in vec2				texCoord;
uniform sampler2D		texImage;
out vec4			fragColour;

void main() {
	fragColour = texture( texImage, texCoord );
}

What it produces is at i.imgur.com/2VBbfUF.png (Sorry, I can’t post the link because I’m so new).

The tiny square in the top left is the actual texture and you can see how it’s rendering it. If I had to take a wild ass guess, I’d say it’s using the same uv in the fragment shader for every outbound pixel but I don’t know why so if anyone has a theory about what is or isn’t firing (or even if you see something I’ve done that’s just terrible or deprecated) please let me know.

Also, I have absolutely no idea what glUniform1i(uniforms[UNIFORM_TEXTURE], 0); does. Doesn’t GL_TEXTURE0 activate the first texture register? Why do we need to pass ‘0’ to the uniform as well?

glActiveTexture(GL_TEXTURE0);
glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
glBindSampler(0, samplers[SAMPLER_TILE])