#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,vertices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,20,(const void*)0);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,20,(const 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_COMPRESSED_RGB_S3TC_DXT1_EXT,texturedimensions,texturedimensions,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_UNSIGNED_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;
}