diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85bf863cd310fd3062f8c94f06e0c0db7e5c9b13..20a570a442246d033dd72c34a57252f71ee6b4c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -251,6 +251,8 @@ IF(VITE_ENABLE_VBO) render/vbo.hpp render/Shader.hpp render/Render_alternate.hpp + render/text2D.hpp + render/texture.hpp ) SET(VITE_SRCS @@ -258,6 +260,8 @@ IF(VITE_ENABLE_VBO) render/vbo.cpp render/Shader.cpp render/Render_alternate.cpp + render/text2D.cpp + render/texture.cpp ) ENDIF(VITE_ENABLE_VBO) diff --git a/src/render/GanttDiagram.hpp b/src/render/GanttDiagram.hpp index c81714a75eb10ddc24e317b1235d971c7c26a10b..e5a4fc8925f805055ef62486e35205e20a70a2a7 100644 --- a/src/render/GanttDiagram.hpp +++ b/src/render/GanttDiagram.hpp @@ -67,7 +67,7 @@ struct Container_text_{ /*! * \brief Coordinates. */ - Element_pos x, y; + Element_pos x, y, size; /*! * \brief Text. */ @@ -238,7 +238,7 @@ public: _container_texts[i].x *= (Info::Render::width/Info::Container::x_max)*_x_scale_container_state; _container_texts[i].y = trace_to_render_y(_container_texts[i].y);// + _render_height-_ruler_height)*coeff_trace_render_y(); - drawing_instance->draw_text(_container_texts[i].x, _container_texts[i].y, _z_container+1, _container_texts[i].value); + drawing_instance->draw_text(_container_texts[i].x, _container_texts[i].y, /*_z_container+1*/_containers[i].w * (Info::Render::width/Info::Container::x_max)*_x_scale_container_state, _container_texts[i].value); } drawing_instance->end_draw_containers(); diff --git a/src/render/Render_alternate.cpp b/src/render/Render_alternate.cpp index 043b1dd1b681babeab3b6f384180fcd9d93d47c4..1a27cb4729265c8207a2d71c56e148afea158fd8 100644 --- a/src/render/Render_alternate.cpp +++ b/src/render/Render_alternate.cpp @@ -68,6 +68,7 @@ #include "render/Render_alternate.hpp" #include "render/GanttDiagram.hpp" #include "render/Shader.hpp" +#include "render/text2D.hpp" /* -- */ #include "core/Core.hpp" #include "render/vbo.hpp" @@ -104,6 +105,7 @@ Render_alternate::Render_alternate(Core* core, QWidget *parent, const QGLFormat& Render_alternate::~Render_alternate(){ + cleanupText2D(); } /*********************************** @@ -135,6 +137,7 @@ void Render_alternate::initializeGL() { std::cout << "init ok" << std::endl; _modelview = glm::scale(_modelview, glm::vec3(1,-1,1)); _modelview = glm::translate(_modelview, glm::vec3(0,-Info::Render::height, 0)); + initText2D("Holstein.DDS"); } void Render_alternate::resizeGL(int width, int height) { @@ -184,7 +187,7 @@ void Render_alternate::paintGL(){ /* drawing containers*/ _containers.lock(); //_modelview = glm::translate(_modelview, glm::vec3(0.0f, _ruler_y + _ruler_height -_y_state_translate, _z_container)); - //_modelview = glm::scale(_modelview, glm::vec3(_x_scale_container_state/0.20, _y_state_scale, 1.0)); + _modelview = glm::scale(_modelview, glm::vec3(_x_scale_container_state/0.20, _y_state_scale, 1.0)); glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(_modelview)); glUniformMatrix4fv(glGetUniformLocation(_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(_projection)); glDrawArrays(GL_QUADS, 0, _containers.getNbVertex()); @@ -229,10 +232,23 @@ void Render_alternate::paintGL(){ //restore matrix _modelview = tmp; } + // _containers.display(_modelview); //rendu //deselect shader glUseProgram(0); + //_modelview = glm::translate(_modelview, glm::vec3(0.0, -100*Info::Render::height, 0.0)); + //_modelview = glm::scale(_modelview, glm::vec3(1000,100,1)); + for(int i=0; i<_texts.size(); i++){ + glm::vec4 current(_texts[i].x, _texts[i].y, 0.0, 1.0); + //we get coordinates beetween (-1 ; 1) + current = _projection * _modelview * current; + //conversion to (0,800) and (0,600) corresponding to the size of the texture used + current[0] = current[0] * 400 + 400; + current[1] = current[1] * 300 + 300; + printText2D(_texts[i].value.c_str(), current[0], current[1], _texts[i].size, _projection, _modelview); + } + _modelview = tmp; // Render_alternate::QGLWidget::setFocus(Qt::ActiveWindowFocusReason);/* give the focus to the render area for mouse and keyboard events */ @@ -664,16 +680,15 @@ void Render_alternate::set_color(float r, float g, float b){ _b = b; } -void Render_alternate::draw_text(const Element_pos x, const Element_pos y, const Element_pos, const std::string s){ +void Render_alternate::draw_text(const Element_pos x, const Element_pos y, const Element_pos size, const std::string s){ if (_draw_ruler) return;/* do not draw text for ruler */ - - Container_text_ buf; - - buf.x = x; - buf.y = render_to_trace_y(y);/* Cancel previous transformation. */ - buf.value = s; - - //_texts.push_back(buf); + const Element_pos offset_y = -_ruler_y - _ruler_height; + Container_text_ buf; + buf.x = x; + buf.y = y + offset_y; //render_to_trace_y(y);/* Cancel previous transformation. */ + buf.value = s; + buf.size = size; + _texts.push_back(buf); } @@ -692,8 +707,8 @@ void Render_alternate::draw_quad(Element_pos x, Element_pos y, Element_pos z, El else if(_draw_states){ offset_x = -_default_entity_x_translate; _states.add(x+offset_x , y+offset_y , _r, _g, _b); - _states.add(x+offset_x+w, y+offset_y , _r, _g, _b); - _states.add(x+offset_x+w, y+offset_y+h, _r, _g, _b); + _states.add(x+offset_x+w, y+offset_y , _r/2, _g/2, _b/2); + _states.add(x+offset_x+w, y+offset_y+h, _r/2, _g/2, _b/2); _states.add(x+offset_x , y+offset_y+h, _r, _g, _b); diff --git a/src/render/Render_alternate.hpp b/src/render/Render_alternate.hpp index ddee5c2a7c9deb54387a819b6ec726e0c41c380b..cc41482a9c3518b57b8ceafaf815280a4f0e6b37 100644 --- a/src/render/Render_alternate.hpp +++ b/src/render/Render_alternate.hpp @@ -125,7 +125,7 @@ protected: */ // GLuint _wait_list; - //std::vector _texts; + std::vector _texts; //std::vector _arrows; //std::vector _circles; Vbo _containers; diff --git a/src/render/text2D.cpp b/src/render/text2D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65e6c4af4fa6f2a6202ebe285478e6f5b21c017c --- /dev/null +++ b/src/render/text2D.cpp @@ -0,0 +1,128 @@ +#include +#include + +#include +#define GLM_FORCE_RADIANS +#include +#include +#include +using namespace glm; + +#include "Shader.hpp" +#include "texture.hpp" + +#include "text2D.hpp" + +unsigned int Text2DTextureID; +unsigned int Text2DVertexBufferID; +unsigned int Text2DUVBufferID; +Shader* _shader; +unsigned int Text2DUniformID; + +void initText2D(const char * texturePath){ + + // Initialize texture + Text2DTextureID = loadDDS(texturePath); + + // Initialize VBO + glGenBuffers(1, &Text2DVertexBufferID); + glGenBuffers(1, &Text2DUVBufferID); + + // Initialize Shader + _shader = new Shader("TextVertexShader.vertexshader", "TextVertexShader.fragmentshader"); + _shader->charger(); + + // Initialize uniforms' IDs + Text2DUniformID = glGetUniformLocation( _shader->getProgramID(), "myTextureSampler" ); + +} + +void printText2D(const char * text, int x, int y, int size, glm::mat4 projection, glm::mat4 modelview){ + + unsigned int length = strlen(text); + + // Fill buffers + std::vector vertices; + std::vector UVs; + for ( unsigned int i=0 ; igetProgramID()); + + // Bind texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, Text2DTextureID); + // Set our "myTextureSampler" sampler to user Texture Unit 0 + glUniform1i(Text2DUniformID, 0); + +glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(modelview)); +glUniformMatrix4fv(glGetUniformLocation(_shader->getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(projection)); + + // 1rst attribute buffer : vertices + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, Text2DVertexBufferID); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 ); + + // 2nd attribute buffer : UVs + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, Text2DUVBufferID); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 ); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Draw call + glDrawArrays(GL_TRIANGLES, 0, vertices.size() ); + + glDisable(GL_BLEND); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + +} + +void cleanupText2D(){ + + // Delete buffers + glDeleteBuffers(1, &Text2DVertexBufferID); + glDeleteBuffers(1, &Text2DUVBufferID); + + // Delete texture + glDeleteTextures(1, &Text2DTextureID); + + // Delete shader + glDeleteProgram(_shader->getProgramID()); +} diff --git a/src/render/text2D.hpp b/src/render/text2D.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5ce3569b970ffe3f12d59d1b11dc052cedf01c47 --- /dev/null +++ b/src/render/text2D.hpp @@ -0,0 +1,8 @@ +#ifndef TEXT2D_HPP +#define TEXT2D_HPP + +void initText2D(const char * texturePath); +void printText2D(const char * text, int x, int y, int size, glm::mat4, glm::mat4); +void cleanupText2D(); + +#endif diff --git a/src/render/texture.cpp b/src/render/texture.cpp new file mode 100644 index 0000000000000000000000000000000000000000..403936c6830e0f3cddca74ead6f42e8af7f0df6c --- /dev/null +++ b/src/render/texture.cpp @@ -0,0 +1,211 @@ +#include +#include +#include + +#include + +//#include + + +/*GLuint loadBMP_custom(const char * imagepath){ + + printf("Reading image %s\n", imagepath); + + // Data read from the header of the BMP file + unsigned char header[54]; + unsigned int dataPos; + unsigned int imageSize; + unsigned int width, height; + // Actual RGB data + unsigned char * data; + + // Open the file + FILE * file = fopen(imagepath,"rb"); + if (!file) {printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); return 0;} + + // Read the header, i.e. the 54 first bytes + + // If less than 54 bytes are read, problem + if ( fread(header, 1, 54, file)!=54 ){ + printf("Not a correct BMP file\n"); + return 0; + } + // A BMP files always begins with "BM" + if ( header[0]!='B' || header[1]!='M' ){ + printf("Not a correct BMP file\n"); + return 0; + } + // Make sure this is a 24bpp file + if ( *(int*)&(header[0x1E])!=0 ) {printf("Not a correct BMP file\n"); return 0;} + if ( *(int*)&(header[0x1C])!=24 ) {printf("Not a correct BMP file\n"); return 0;} + + // Read the information about the image + dataPos = *(int*)&(header[0x0A]); + imageSize = *(int*)&(header[0x22]); + width = *(int*)&(header[0x12]); + height = *(int*)&(header[0x16]); + + // Some BMP files are misformatted, guess missing information + if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component + if (dataPos==0) dataPos=54; // The BMP header is done that way + + // Create a buffer + data = new unsigned char [imageSize]; + + // Read the actual data from the file into the buffer + fread(data,1,imageSize,file); + + // Everything is in memory now, the file wan be closed + fclose (file); + + // Create one OpenGL texture + GLuint textureID; + glGenTextures(1, &textureID); + + // "Bind" the newly created texture : all future texture functions will modify this texture + glBindTexture(GL_TEXTURE_2D, textureID); + + // Give the image to OpenGL + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); + + // OpenGL has now copied the data. Free our own version + delete [] data; + + // Poor filtering, or ... + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // ... nice trilinear filtering. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + + // Return the ID of the texture we just created + return textureID; +} + +// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, +// or do it yourself (just like loadBMP_custom and loadDDS) +//GLuint loadTGA_glfw(const char * imagepath){ +// +// // Create one OpenGL texture +// GLuint textureID; +// glGenTextures(1, &textureID); +// +// // "Bind" the newly created texture : all future texture functions will modify this texture +// glBindTexture(GL_TEXTURE_2D, textureID); +// +// // Read the file, call glTexImage2D with the right parameters +// glfwLoadTexture2D(imagepath, 0); +// +// // Nice trilinear filtering. +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// glGenerateMipmap(GL_TEXTURE_2D); +// +// // Return the ID of the texture we just created +// return textureID; +//} + + + */ +#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII +#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII +#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII + +GLuint loadDDS(const char * imagepath){ + + unsigned char header[124]; + + FILE *fp; + + /* try to open the file */ + fp = fopen(imagepath, "rb"); + if (fp == NULL){ + printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath); getchar(); + return 0; + } + + /* verify the type of file */ + char filecode[4]; + fread(filecode, 1, 4, fp); + if (strncmp(filecode, "DDS ", 4) != 0) { + fclose(fp); + return 0; + } + + /* get the surface desc */ + fread(&header, 124, 1, fp); + + unsigned int height = *(unsigned int*)&(header[8 ]); + unsigned int width = *(unsigned int*)&(header[12]); + unsigned int linearSize = *(unsigned int*)&(header[16]); + unsigned int mipMapCount = *(unsigned int*)&(header[24]); + unsigned int fourCC = *(unsigned int*)&(header[80]); + + + unsigned char * buffer; + unsigned int bufsize; + /* how big is it going to be including all mipmaps? */ + bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize; + buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char)); + fread(buffer, 1, bufsize, fp); + /* close the file pointer */ + fclose(fp); + + unsigned int components = (fourCC == FOURCC_DXT1) ? 3 : 4; + unsigned int format; + switch(fourCC) + { + case FOURCC_DXT1: + format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + case FOURCC_DXT3: + format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case FOURCC_DXT5: + format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + default: + free(buffer); + return 0; + } + + // Create one OpenGL texture + GLuint textureID; + glGenTextures(1, &textureID); + + // "Bind" the newly created texture : all future texture functions will modify this texture + glBindTexture(GL_TEXTURE_2D, textureID); + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + + unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; + unsigned int offset = 0; + + /* load the mipmaps */ + for (unsigned int level = 0; level < mipMapCount && (width || height); ++level) + { + unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize; + glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, + 0, size, buffer + offset); + + offset += size; + width /= 2; + height /= 2; + + // Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter. + if(width < 1) width = 1; + if(height < 1) height = 1; + + } + + free(buffer); + + return textureID; + + +} diff --git a/src/render/texture.hpp b/src/render/texture.hpp new file mode 100644 index 0000000000000000000000000000000000000000..db620fc0245fd345b34f187a4769f0c263635c19 --- /dev/null +++ b/src/render/texture.hpp @@ -0,0 +1,16 @@ +#ifndef TEXTURE_HPP +#define TEXTURE_HPP + +// Load a .BMP file using our custom loader +//GLuint loadBMP_custom(const char * imagepath); + +//// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library, +//// or do it yourself (just like loadBMP_custom and loadDDS) +//// Load a .TGA file using GLFW's own loader +//GLuint loadTGA_glfw(const char * imagepath); + +// Load a .DDS file using GLFW's own loader +GLuint loadDDS(const char * imagepath); + + +#endif