[VBO][GLSL] Problem with texturing

I want texture a cube in my program. I’m using VBO and GLSL. I hope that you can help me. This is the code (sorry about that, but I don’t know what can I solve this):


#define GLFW_DLL

#include <iostream>

#include <GL/glew.h>
#include <GL/glfw.h>
#include <GL/glut.h>

#include "ShaderLoader.h"
#include "SetShader.h"
#include "VersionCheck.h"

extern GLuint Program, vsID, fsID;

GLuint texID;

GLuint boxID;

GLuint texture;
GLuint textureLocation;

GLfloat * Box = new GLfloat[72];
GLfloat * Tex = new GLfloat[8];

int Width;
int Height;

bool obrot = false;

void GLFWCALL ChangeSize(int Width, int Height)
{
	if(Height == 0) Height = 1;

    glViewport(0,0,Width,Height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(GLfloat)Width/(GLfloat)Height,1,1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

	gluLookAt(0.0f,0.0f,6.0,0.0,0.0,0.0,0.0,1.0,0.0);
}

void RenderScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0,0.0,0.0,1.0);

	glBindBuffer(GL_ARRAY_BUFFER,boxID);
	glBufferData(GL_ARRAY_BUFFER,sizeof(float)*72,Box,GL_DYNAMIC_DRAW);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3,GL_FLOAT,0,0);
	glEnableVertexAttribArray(glGetAttribLocation(Program,"tex_in"));
    	glBindBuffer(GL_ARRAY_BUFFER,texID);
	glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,Tex,GL_DYNAMIC_DRAW);
	glVertexAttribPointer(glGetAttribLocation(Program,"tex_in"), 2, GL_FLOAT, GL_FALSE, 0, 0);

	glDrawArrays(GL_QUADS,0,72);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,texture);
	glEnable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
	glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

	textureLocation = glGetUniformLocation(Program,"texture");
	glUniform1i(textureLocation,0);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	if(obrot == true) glRotatef(10,1,1,1);
}

void GLFWCALL My_Key_Callback(int key, int action)
{
  if(key == GLFW_KEY_ESC && action == GLFW_PRESS) exit(1);
  else if(key == ',' && action == GLFW_PRESS) glRotatef(-5.0f,0.0f,1.0f,0.0f);
  else if(key == '.' && action == GLFW_PRESS) glRotatef( 5.0f,0.0f,1.0f,0.0f);
  else if(key == ' ' && action == GLFW_PRESS) obrot = true;
  else if(key == '/' && action == GLFW_PRESS) obrot = false;
}

GLuint LoadTexture(const char * FileName, int Width, int Height)
{
	GLuint Texture;
	unsigned char * Data;
	FILE * File;

	File = fopen(FileName, "rb");
	if(File == NULL)
	{
		std::cout << "Texture isn't exist!
";
		return 0;
	}
	Data = (unsigned char *)malloc(Width * Height * 3);
	fread(Data, Width * Height * 3, 1, File);
	fclose(File);

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

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,Width,Height,0,GL_RGB,GL_UNSIGNED_BYTE,Data);

	free(Data);
	
	return Texture;
}

int main(int argc, char **argv)
{
	glfwInit();
	glfwOpenWindow(320,320,8,8,8,8,24,0,GLFW_WINDOW);
	glfwSetWindowTitle("OpenGL");

	glewInit();

	GLEWVersion("Ready for GLSL.","GLSL not supported.");
	GLFWVersion();

	glfwSwapInterval(1);
	glfwSetKeyCallback(My_Key_Callback);
	glfwSetWindowSizeCallback(ChangeSize);

	Box[0] = -1.0; Box[1] = -1.0; Box[2] = 1.0;
	Box[3] = 1.0; Box[4] = -1.0; Box[5] = 1.0;
	Box[6] = 1.0; Box[7] = 1.0; Box[8] = 1.0;
	Box[9] = -1.0; Box[10] = 1.0; Box[11] = 1.0;

	Box[12] = 1.0; Box[13] = -1.0; Box[14] = 1.0;
	Box[15] = 1.0; Box[16] = -1.0; Box[17] = -1.0;
	Box[18] = 1.0; Box[19] = 1.0; Box[20] = -1.0;
	Box[21] = 1.0; Box[22] = 1.0; Box[23] = 1.0;

	Box[24] = 1.0; Box[25] = -1.0; Box[26] = -1.0;
	Box[27] = -1.0; Box[28] = -1.0; Box[29] = -1.0;
	Box[30] = -1.0; Box[31] = 1.0; Box[32] = -1.0;
	Box[33] = 1.0; Box[34] = 1.0; Box[35] = -1.0;

	Box[36] = -1.0; Box[37] = -1.0; Box[38] = -1.0;
	Box[39] = -1.0; Box[40] = -1.0; Box[41] = 1.0;
	Box[42] = -1.0; Box[43] = 1.0; Box[44] = 1.0;
	Box[45] = -1.0; Box[46] = 1.0; Box[47] = -1.0;

	Box[48] = -1.0; Box[49] = 1.0; Box[50] = 1.0;
	Box[51] = 1.0; Box[52] = 1.0; Box[53] = 1.0;
	Box[54] = 1.0; Box[55] = 1.0; Box[56] = -1.0;
	Box[57] = -1.0; Box[58] = 1.0; Box[59] = -1.0;

	Box[60] = -1.0; Box[61] = -1.0; Box[62] = 1.0;
	Box[63] = 1.0; Box[64] = -1.0; Box[65] = 1.0;
	Box[66] = 1.0; Box[67] = -1.0; Box[68] = -1.0;
	Box[69] = -1.0; Box[70] = -1.0; Box[71] = -1.0;

	Tex[0] = 0.0; Tex[1] = 0.0;
	Tex[2] = 1.0; Tex[3] = 0.0;
	Tex[4] = 1.0; Tex[5] = 1.0;
	Tex[6] = 0.0; Tex[7] = 1.0;

	setShaders("myShader.vert.txt","myShader.frag.txt");

	glGenBuffers(1,&boxID);
	glBindBuffer(GL_ARRAY_BUFFER,boxID);
	glBufferData(GL_ARRAY_BUFFER,sizeof(float)*72,Box,GL_DYNAMIC_DRAW);

	glGenBuffers(1,&texID);
	glBindBuffer(GL_ARRAY_BUFFER,texID);
	glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,Tex,GL_DYNAMIC_DRAW);

	texture = LoadTexture("texture.raw",256,256);

	while(1)
	{
		RenderScene();
		glfwSwapBuffers();
	}

	glUseProgram(0);
    	glDetachShader(Program,vsID);
    	glDetachShader(Program,fsID);
	glDeleteShader(vsID);
    	glDeleteShader(fsID);
    	glDeleteProgram(Program);

	glfwTerminate();
	exit(1);
}

Vertex:


attribute vec2 tex_in;

void main()
{
	tex_in = gl_TexCoord[0];
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();
}

Fragment:


uniform sampler2D texture;

void main()
{
	vec4 color = texture2D(texture,gl_TexCoord[0].st);
	gl_FragColor = color;
}

Problem is that, I see not textured cube, but a cube in color of one pixel from texture.

Texture is well loaded, because I’m using this tex in other program, but I render one wall, not 3D cube.

There are many things to say about your code…

I think that your main problem is that your ‘Box’ and ‘Tex’ buffers should have the same number of items (24) : each vertex should have one position and one texture coordinate.

Also, your call to ‘glDrawArrays(GL_QUADS,0,72);’ should be 24 instead of 72 : you only have 24 items in your array (but 72 floats, as you have 3 floats per item)

Also note that you don’t have to refill the VBOs before each draw call, you can do it only once.