PDA

View Full Version : [VBO][GLSL] Problem with texturing



Rares
09-27-2009, 01:13 AM
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(Prog ram,"tex_in"));
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,Tex,G L_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 &amp;&amp; action == GLFW_PRESS) exit(1);
else if(key == ',' &amp;&amp; action == GLFW_PRESS) glRotatef(-5.0f,0.0f,1.0f,0.0f);
else if(key == '.' &amp;&amp; action == GLFW_PRESS) glRotatef( 5.0f,0.0f,1.0f,0.0f);
else if(key == ' ' &amp;&amp; action == GLFW_PRESS) obrot = true;
else if(key == '/' &amp;&amp; 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!\n";
return 0;
}
Data = (unsigned char *)malloc(Width * Height * 3);
fread(Data, Width * Height * 3, 1, File);
fclose(File);

glGenTextures(1, &amp;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,&amp;boxID);
glBindBuffer(GL_ARRAY_BUFFER,boxID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*72,Box, GL_DYNAMIC_DRAW);

glGenBuffers(1,&amp;texID);
glBindBuffer(GL_ARRAY_BUFFER,texID);
glBufferData(GL_ARRAY_BUFFER,sizeof(float)*8,Tex,G L_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.

Nicolas Lelong
09-27-2009, 03:04 PM
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.