PDA

View Full Version : Problem - DXT1 textures not displaying



MaToVy
12-08-2012, 09:13 AM
[RESOLVED]

Forgot to generate a sampler... Guess I could have waited couple of hours before posting this...

*Problem:
Model with DXT1 compressed texture appears black.

*Background info:
I made two programs, one converts Wavefront OBJ file, its MTL file and associated DDS texture to one file of my specification.
The second one is meant to be used as a viewer for those "myfiles". This is the program with which I have the problem.

*Full code of the "viewer"(it was meant as a simple quickie to display one model so it's all-in-one and not-so-pretty):
-Program
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <fstream>
#include <string>

int main(int argc,char** argv)
{
if(argc!=2) return -1;
//Create window, context, initialize glew.
sf::Window screen(sf::VideoMode(500,500),"DigiViewer",sf::Style::Titlebar|sf::Style::Close);
glewInit();

//Helpful variables.
bool running(true);
sf::Event event;
std::string linebuffer("");
sf::Clock timer;
sf::Time frameduration;

//OpenGL stuff setup.
glClearColor(0.15f,0.15f,0.15f,1.0f);
glEnable(GL_DEPTH_TEST);

//Load and compile vertex shader.
std::string vshadercode("");
std::ifstream vshaderfile("v.glsl");
while(getline(vshaderfile,linebuffer)) vshadercode+=linebuffer+"\n";
vshaderfile.close();
const char* vshadercode0=vshadercode.c_str();
unsigned int vshader=glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vshader,1,&vshadercode0,NULL);
glCompileShader(vshader);

//Load and compile fragment shader.
std::string fshadercode("");
std::ifstream fshaderfile("f.glsl");
while(getline(fshaderfile,linebuffer)) fshadercode+=linebuffer+"\n";
fshaderfile.close();
const char* fshadercode0=fshadercode.c_str();
unsigned int fshader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fshader,1,&fshadercode0,NULL);
glCompileShader(fshader);

//Link program.
unsigned int program=glCreateProgram();
glAttachShader(program,vshader);
glAttachShader(program,fshader);
glLinkProgram(program);
glDeleteShader(fshader);
glDeleteShader(vshader);

//VAO creation, binding. Setting tex. unit 0 as active unit.
unsigned int vertexarray(0);
glGenVertexArrays(1,&vertexarray);
glBindVertexArray(vertexarray);
glActiveTexture(GL_TEXTURE0);

/*Load myfile. Spec:
6 bytes - magic number MYFILE(don't bother checking it)
2 bytes unsigned short - number of vertices
2 bytes unsigned short - number of indices
2 bytes unsigned short - texture width=height in texels(texture is square)
4 bytes unsigned int - texture linear size
number of vertices * 5(xyzuv) *4(float) bytes - table of vertices
number of indices * 2(short) bytes - table of indices
size bytes - texture data*/

unsigned short verticescount(0);
unsigned short indicescount(0);
unsigned short texturedimensions(0);
unsigned int linearsize(0);

std::ifstream model(argv[1],std::ios_base::in|std::ios_base::binary);
model.seekg(6,std::ios::beg);
model.read((char*)&verticescount,2);
model.read((char*)&indicescount,2);
model.read((char*)&texturedimensions,2);
model.read((char*)&linearsize,4);
float* vertices=new float[verticescount*5];
model.read((char*)vertices,verticescount*20);
unsigned short* indices=new unsigned short[indicescount];
model.read((char*)indices,indicescount*2);
unsigned char* texturedata=new unsigned char[linearsize];
model.read((char*)texturedata,linearsize);
model.close();

/////////////////////REMOVE////////////////////
std::ofstream test0("test.txt");
test0.close();
std::ofstream test("test.txt",std::ios_base::out|std::ios_base::app);
test<<"Vertices count: "<<verticescount<<"\n";
test<<"Indices count: "<<indicescount<<" ("<<indicescount/3<<" faces)\n";
test<<"Texture dimensions: "<<texturedimensions<<"x"<<texturedimensions<<"\n";
test<<"\nVertices:\n";
for(unsigned short i(0);i<verticescount;i++) test<<i<<" x:"<<vertices[(i*5)]<<" y:"<<vertices[(i*5)+1]<<" z:"<<vertices[(i*5)+2]<<" u:"<<vertices[(i*5)+3]<<" v:"<<vertices[(i*5)+4]<<"\n";
test<<"\nIndices:\n";
for(unsigned short i(0);i<indicescount;i++)
{
if(i%3==0) test<<"f: ";
test<<indices[i]<<" ";
if(i%3==2) test<<"\n";
}
test.close();
////////////////////////////////////////////////

//VBO creation, binding, buffering in data for vertices(x,y,z,u,v in floats, positions to 0, texcoords to 1)
unsigned int vertexbuffer(0);
glGenBuffers(1,&vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER,vertexbuffer);
glBufferData(GL_ARRAY_BUFFER,verticescount*20,vert ices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,20,(co nst void*)0);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,20,(co nst void*)12);

//VBO creation, binding, buffering data for indices.
unsigned int indexbuffer(0);
glGenBuffers(1,&indexbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indicescount* 2,indices,GL_STATIC_DRAW);

//Texture creation, binding, buffering image data.
//Only width=height and size are variables, other attributes of image(mipmap,compression) are const across any potential loaded images as I make them myself.
unsigned int texture(0);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESS ED_RGB_S3TC_DXT1_EXT,texturedimensions,texturedime nsions,0,linearsize,texturedata);

//Creating uniform for the texture at unit 0.
unsigned int mysampler=glGetUniformLocation(program,"mysampler");
glUniform1i(mysampler,0);

//Enable and use everything.
glUseProgram(program);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

do
{
//Some stuff to do each frame.
frameduration=timer.restart();
while(screen.pollEvent(event)) if(event.type==sf::Event::Closed) running=false;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

//Draw the current element buffer and show it.
glDrawElements(GL_TRIANGLES,indicescount,GL_UNSIGN ED_SHORT,0);
screen.display();
}
while(running);

//Get rid of OGL objects.
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDeleteTextures(1,&texture);
glDeleteBuffers(1,&indexbuffer);
glDeleteBuffers(1,&vertexbuffer);
glDeleteVertexArrays(1,&vertexarray);

//Bye bye.
screen.close();

return 0;
}

-V. shader
#version 330 core

//x,y,z floats
layout(location=0) in vec3 vertexposition;
//u,v floats
layout(location=1) in vec2 vertexuv;
//Just pass this to the f.shader
out vec2 fragmentuv;

void main()
{
gl_Position=vec4(vertexposition,1.0f);
fragmentuv=vertexuv;
}

-F. shader
#version 330 core

//Our sampler from loaded image
uniform sampler2D mysampler;
in vec2 fragmentuv;
out vec3 color;

void main()
{
color=texture2D(mysampler,fragmentuv).rgb;
}


So this is what I do texturewise:
I'm setting texture unit 0 as an active one

glActiveTexture(GL_TEXTURE0);
I'm creating and binding a texture

unsigned int texture(0);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
I'm sending all the texture data: texturedimensions is the width/height, linearsize is, well, linearsize and texture data is the raw image data, all from dds file.

glCompressedTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESS ED_RGB_S3TC_DXT1_EXT,texturedimensions,texturedime nsions,0,linearsize,texturedata);
I'm getting uniform id and binding it to tex. unit 0 - the currently bound texture

unsigned int mysampler=glGetUniformLocation(program,"mysampler");
glUniform1i(mysampler,0);
In my fragment shader I get the sampler uniform

uniform sampler2D mysampler;
And use it to sample colors for the fragments

color=texture2D(mysampler,fragmentuv).rgb;

At this point I'm pretty sure thats everything I need. But the texture does not appear, the model is black. I checked and both shaders compile without problem, the program links OK too, there are no errors after glCompressedTexImage2D, my graphic card supports EXT_texture_compression_s3tc so I don't know why it doesn't work (let's word it better - I don't see it yet, but I spent 48 hours on looking at this code). I also thought that the first program, the converting one might be saving the raw DXT1 image data wrongly, but I really doubt it (I can provide its code as well if needed).

I would be really grateful if someone could enlighten me and point out the problem. Thank you in advance.