void CGLSLRayCasting::init(const string& _vertfile,const string& _fragfile){
	
	m_SimpleVertexShader = CreateShaderFromFile(_vertfile);
	
	m_FragmentShader = CreateShaderFromFile(_fragfile);
	m_Program = glCreateProgram();
	glAttachShader(m_Program, m_SimpleVertexShader);
	glAttachShader(m_Program, m_FragmentShader);GetGLError("glTexImage3D");
	glLinkProgram(m_Program);
	string names[]={"voltexture","threshold"};
	for(int i=0;i<sizeof(names)/sizeof(names[0]);i++){
		m_Map[0].insert(pair<string,int>(names[i],glGetUniformLocation(m_Program,names[i].c_str())));
		
	}GetGLError("glTexImage3D");
	glUseProgram(m_Program);
	glUniform1f(m_Map[0]["threshold"],m_threshold);
	glUniform1i(m_Map[0]["voltexture"],0);
	glUseProgram(0);
	m_SliceVertexShader= CreateShaderFromFile("slice.vert");
	m_SliceProgram = glCreateProgram();GetGLError("glTexImage3D");
	glAttachShader(m_SliceProgram, m_SliceVertexShader);GetGLError("glTexImage3D");
	glAttachShader(m_SliceProgram, m_FragmentShader);GetGLError("glTexImage3D");
	glLinkProgram(m_SliceProgram);GetGLError("glTexImage3D");
	checklinkstatus(m_SliceProgram);GetGLError("glTexImage3D");
	glUseProgram(m_SliceProgram);GetGLError("glTexImage3D");
	string names2[]={"voltexture","threshold"};//,"frontIdx"};
	for(int i=0;i<sizeof(names2)/sizeof(names2[0]);i++){
		m_Map[1].insert(pair<string,int>(names2[i],
			glGetUniformLocation(m_SliceProgram,names2[i].c_str())));GetGLError("glTexImage3D");
	}
	
	
	
}
void CGLSLRayCasting::GetLocations(){
	string names[]={"voltexture","threshold"};
	for(int i=0;i<sizeof(names)/sizeof(names[0]);i++){
		m_Map[0].insert(pair<string,int>(names[i],glGetUniformLocation(m_Program,names[i].c_str())));
		if(m_Map[0][names[i]]<0){assert(!"存在しないユニフォーム変数名");}
		GetGLError("glTexImage3D");
	}
}
Exemple #3
0
void CPlyRender::InitCubeMapping(void)
{
	GLenum target[]={
		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
	};
	stringstream filename;



	glGenTextures(1,  &mTexId[CUBEMAP]);
	glBindTexture(GL_TEXTURE_CUBE_MAP, mTexId[CUBEMAP]);
	for(int i=0;i<6;i++){
		filename.str("");
		filename << "../data/cubemap/" << CUBENAME << "/" << CUBEMAP_IMAGE_NAMES[i] << ".jpg";
		cv::Mat img = cv::imread(filename.str().c_str());
		cv::flip(img, img, 0);
		if (img.data == nullptr) { 
			tr2::sys::path mypath;
			cout << "current directory:" << tr2::sys::current_path().string() << endl;
			cout << "tried to open file:" << filename.str() << endl;
			assert(!"cubemap image not found");
		}

		
		glTexImage2D ( target[i], 0, GL_RGB, img.size().width,img.size().height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
	}
	/*  glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
        glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
        glfwFreeImage(&img);
        return true;
    }*/
	// テクスチャを拡大・縮小する方法の指定 
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	
	// テクスチャの繰り返し方法の指定 
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
	// キューブマッピング用のテクスチャ座標を生成する 
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);

	/* 設定対象を無名テクスチャに戻す */
	glBindTexture(GL_TEXTURE_2D, 0);
	GetGLError("teximage2d");

}
Exemple #4
0
void DrawSkybox::init(const std::vector<std::string>& faceFiles, const struct Shader& shader) {

    Texture<unsigned char> textpx = make2DTexture(faceFiles[0].c_str(), true, true);
    cube_.textId_[DrawObject::eText0] = makeGL2DTexture(textpx);
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    
    Texture<unsigned char> textnx = make2DTexture(faceFiles[1].c_str(), true, true);
    cube_.textId_[DrawObject::eText1] = makeGL2DTexture(textnx);
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    
    cube_.textId_[DrawObject::eText2] = makeGL2DTexture(faceFiles[2].c_str());
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    cube_.textId_[DrawObject::eText3] = makeGL2DTexture(faceFiles[3].c_str());
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    cube_.textId_[DrawObject::eText4] = makeGL2DTexture(faceFiles[4].c_str());
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    Texture<unsigned char> textnz = make2DTexture(faceFiles[5].c_str(), true, true);
    cube_.textId_[DrawObject::eText5] = makeGL2DTexture(textnz);
    SetGLTextureFilter(GL_TEXTURE_2D, GL_LINEAR, GL_LINEAR);
    SetGLTextureBorder(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);

    GetGLError();
    
    Object obj;
    for (unsigned i=0;i<24;i++) {
        unsigned ix = 3*i;
        Real3 vx(vertices[ix],vertices[ix+1],vertices[ix+2]);
        obj.vx_.push_back(vx);
    }
    for (unsigned i=0;i<24;i++) {
        unsigned ix = 2*i;
        Real2 uv(tcoords[ix],tcoords[ix+1]);
        obj.uv_.push_back(uv);
    }
    for (unsigned i=0;i<12;i++) {
        unsigned ix = 3*i;
        UShort3 fc(indices[ix],indices[ix+1],indices[ix+2]);
        obj.fc_.push_back(fc);
    }
    cube_.init(obj, GL_STATIC_DRAW);
    cube_.shader_ = &shader;
}
Result GraphicsInterfaceOpenGL::writeTexture2D(void *o_tex, int width, int height, TextureFormat format, const void *buf, size_t)
{
    GLenum gl_format = 0;
    GLenum gl_type = 0;
    GLenum gl_itype = 0;
    GetGLTextureType(format, gl_format, gl_type, gl_itype);

    // available OpenGL 4.5 or later
    // glTextureSubImage2D((GLuint)(size_t)o_tex, 0, 0, 0, width, height, internal_format, internal_type, buf);

    auto ret = Result::OK;
    glBindTexture(GL_TEXTURE_2D, (GLuint)(size_t)o_tex);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, gl_format, gl_type, buf);
    ret = GetGLError();
    glBindTexture(GL_TEXTURE_2D, 0);
    return ret;
}
Result GraphicsInterfaceOpenGL::createTexture2D(void **dst_tex, int width, int height, TextureFormat format, const void *data, ResourceFlags flags)
{
    GLenum gl_format = 0;
    GLenum gl_type = 0;
    GLenum gl_itype = 0;
    GetGLTextureType(format, gl_format, gl_type, gl_itype);

    auto ret = Result::OK;
    GLuint tex = 0;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, gl_itype, width, height, 0, gl_format, gl_type, data);
    ret = GetGLError();
    glBindTexture(GL_TEXTURE_2D, 0);
    *(GLuint*)dst_tex = tex;

    return ret;
}
Result GraphicsInterfaceOpenGL::readTexture2D(void *o_buf, size_t, void *tex, int, int, TextureFormat format)
{
    GLenum gl_format = 0;
    GLenum gl_type = 0;
    GLenum gl_itype = 0;
    GetGLTextureType(format, gl_format, gl_type, gl_itype);

    // available OpenGL 4.5 or later
    // glGetTextureImage((GLuint)(size_t)tex, 0, internal_format, internal_type, bufsize, o_buf);

    sync();

    auto ret = Result::OK;
    glBindTexture(GL_TEXTURE_2D, (GLuint)(size_t)tex);
    glGetTexImage(GL_TEXTURE_2D, 0, gl_format, gl_type, o_buf);
    ret = GetGLError();
    glBindTexture(GL_TEXTURE_2D, 0);
    return ret;
}
Result GraphicsInterfaceOpenGL::readBuffer(void *dst, void *src_buf, size_t read_size, BufferType type)
{
    GLuint buf = (GLuint)(size_t)src_buf;
    GLenum gltype = GetGLBufferType(type);

    Result ret = Result::OK;
    glBindBuffer(gltype, buf);
    void *mapped_data = glMapBuffer(gltype, GL_READ_ONLY);
    if (mapped_data) {
        memcpy(dst, mapped_data, read_size);
        glUnmapBuffer(gltype);
    }
    else {
        ret = GetGLError();
    }
    glBindBuffer(gltype, 0);

    return ret;
}
Result GraphicsInterfaceOpenGL::writeBuffer(void *dst_buf, const void *src, size_t write_size, BufferType type)
{
    GLuint buf = (GLuint)(size_t)dst_buf;
    GLenum gltype = GetGLBufferType(type);

    Result ret = Result::OK;
    glBindBuffer(gltype, buf);
    void *mapped_data = glMapBuffer(gltype, GL_WRITE_ONLY);
    if (mapped_data) {
        memcpy(mapped_data, src, write_size);
        glUnmapBuffer(gltype);
    }
    else {
        ret = GetGLError();
    }
    glBindBuffer(gltype, 0);

    return ret;
}
Exemple #10
0
int FBO::attach() {

    buffers_[eDepth]= createRenderBuffer();
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size_[eWidth], size_[eHeight]);
    
    if (isTexture_) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffers_[eColor], 0);
    }
    else {
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffers_[eColor]);
    }
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffers_[eDepth]);
	
	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)	{
        std::cout<<"failed to make complete framebuffer object:"<<std::endl<<glCheckFramebufferStatus(GL_FRAMEBUFFER);
		return 0;
	}
    
	GetGLError();
    return name_;
}
Result GraphicsInterfaceOpenGL::createBuffer(void **dst_buf, size_t size, BufferType type, const void *data, ResourceFlags flags)
{
    GLenum gltype = GetGLBufferType(type);
    GLenum glusage = GL_STATIC_DRAW;
    if (flags & ResourceFlags::CPU_Write) {
        glusage = GL_DYNAMIC_DRAW;
    }
    if (flags & ResourceFlags::CPU_Read) {
        glusage = GL_STREAM_DRAW;
    }

    auto ret = Result::OK;
    GLuint buf = 0;
    glGenBuffers(1, &buf);
    glBindBuffer(gltype, buf);
    glBufferData(gltype, size, data, glusage);
    ret = GetGLError();
    glBindBuffer(gltype, 0);

    *(GLuint*)dst_buf = buf;
    return ret;
}
void BaseShader::linkProgram() {
    GLint logLength, status;
    glLinkProgram(mProgram);
	glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &logLength);
	if (logLength > 0)
	{
		GLchar *log = (GLchar*)malloc(logLength);
		glGetProgramInfoLog(mProgram, logLength, &logLength, log);
		printf("Program link log:\n%s\n", log);
		free(log);
	}
	
	glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
	if (status == 0)
	{
		printf("Failed to link program");
	}
	
	glValidateProgram(mProgram);
	glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &logLength);
	if (logLength > 0)
	{
		GLchar *log = (GLchar*)malloc(logLength);
		glGetProgramInfoLog(mProgram, logLength, &logLength, log);
		printf("Program validate log:\n%s\n", log);
		free(log);
	}
	
	glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &status);
	if (status == 0)
	{
		printf("Failed to validate program");
	}
    
    printf("prog is: %i\n", mProgram);
	
	GetGLError();
}
  // Called by Rocket when it wants to render application-compiled geometry.		
  void RocketRenderInterface::RenderCompiledGeometry(
    Rocket::Core::CompiledGeometryHandle geometry, 
    const Rocket::Core::Vector2f& translation) {

    if (geometry <= 0) {
      throw runtime_error("RocketRenderInterface::"
        "RenderCompiledGeometry() - ERROR: geometry index = 0!");
    }

    uint32_t i_geometry = static_cast<uint32_t>(geometry);
    ROCKET_SHADER_TYPE cur_shader = _shader_types[i_geometry-1];
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    GetGLError();

    _shader_programs[cur_shader]->bind();

    bindTexture(i_geometry-1);
    GetGLError();

    bindUniforms(cur_shader, translation);
    GetGLError();

    glBindVertexArray(_vao[i_geometry-1]);
    GetGLError();

    glDrawElements(GL_TRIANGLES, _index_size[i_geometry-1], 
      GL_UNSIGNED_INT, BUFFER_OFFSET(0));

    GetGLError();
    glBindVertexArray(0);
    GetGLError();

    unbindTexture();
    GetGLError();
    glDisable(GL_BLEND);
  }
Exemple #14
0
bool ModelData::FormFlippedDisplayLists() //returns opengl error enunum.
{
    unsigned int l;
    unsigned int t;
    const unsigned int listSize = 10000;//each list to be 10000 triangles big.
    unsigned int tSeamCount = 0;

    //first lets free up existing display lists if there are any
    for( l = 0; l < flippedDispLists.size(); l++)
    {
        glDeleteLists(flippedDispLists[l],1);
    }

    if(bypassDispLists)
        return true;


    flippedDispLists.push_back(glGenLists(1));
    if(flippedDispLists.at(flippedDispLists.size()-1) == 0)
        return false;//failure to allocate a list index???

    glNewList(flippedDispLists.at(flippedDispLists.size()-1),GL_COMPILE);
    glBegin(GL_TRIANGLES);// Drawing Using Triangles
    for(t = 0; t < triList.size(); t = t + 1 + displaySkipping)//for each triangle
    {

        glNormal3f(-triList[t].normal.x(),triList[t].normal.y(),triList[t].normal.z());//normals

        glVertex3f( -triList[t].vertex[2].x(), triList[t].vertex[2].y(), triList[t].vertex[2].z());
        glVertex3f( -triList[t].vertex[1].x(), triList[t].vertex[1].y(), triList[t].vertex[1].z());
        glVertex3f( -triList[t].vertex[0].x(), triList[t].vertex[0].y(), triList[t].vertex[0].z());
        //make a new seam.
        if(tSeamCount >= listSize)
        {
            glEnd();
            glEndList();
            flippedDispLists.push_back(glGenLists(1));
            if(flippedDispLists.at(flippedDispLists.size()-1) == 0)
                return false;//failure to allocate a list index???

            //when creating a seam check for graphics error
            int err = GetGLError();
            if(err)
            {
                if(err == GL_OUT_OF_MEMORY)
                {
                    displaySkipping += 10;
                    return FormFlippedDisplayLists();
                }
                else
                    return false;
            }

            glNewList(flippedDispLists.at(flippedDispLists.size()-1),GL_COMPILE);
            glBegin(GL_TRIANGLES);// Drawing Using Triangles
            tSeamCount = 0;
        }

        tSeamCount++;
    }
    glEnd();
    glEndList();

    int err = GetGLError();
    if(err)
    {
        if(err == GL_OUT_OF_MEMORY)
        {
            displaySkipping += 10;
            return FormFlippedDisplayLists();
        }
        else
            return false;
    }

    qDebug() << flippedDispLists.size() << "Flipped Display Lists created for model " << filename;


    return true;

}
BaseShader::BaseShader(const char* vShader, const char* fShader) {
	GLint logLength, status;
    GLchar* sourceString = NULL;
    
    GetGLError();
	
	// Create a program object
	mProgram = glCreateProgram();
    
    GetGLError();
    
    if (vShader){
        // Allocate memory for the source string including the version preprocessor information
        sourceString = getShaderString(vShader, "vsh");
        
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, (const GLchar **)&(sourceString), NULL);
        glCompileShader(vertexShader);
        glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
        
        if (logLength > 0)
        {
            GLchar *log = (GLchar*) malloc(logLength);
            glGetShaderInfoLog(vertexShader, logLength, &logLength, log);
            printf("Vtx shader compiled log: %s\n", log);
            free(log);
        }
        
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
        if (status == 0)
        {
            printf("Failed to compile vtx shader:\n%s\n", sourceString);
        }
        
        free(sourceString);
        sourceString = NULL;
        
        // Attach the vertex shader to our program
        glAttachShader(mProgram, vertexShader);
        
        // Delete the vertex shader since it is now attached
        // to the program, which will retain a reference to it
        glDeleteShader(vertexShader);
    }
    
    if (fShader){
        // Allocate memory for the source string including the version preprocessor	 information
        sourceString = getShaderString(fShader, "fsh");
        
        GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragShader, 1, (const GLchar **)&(sourceString), NULL);
        glCompileShader(fragShader);
        glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0)
        {
            GLchar *log = (GLchar*)malloc(logLength);
            glGetShaderInfoLog(fragShader, logLength, &logLength, log);
            printf("Frag Shader compile log:\n%s\n", log);
            free(log);
        }
        
        glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);
        if (status == 0)
        {
            printf("Failed to compile frag shader:\n%s\n", sourceString);
        }
        
        free(sourceString);
        sourceString = NULL;
        
        // Attach the fragment shader to our program
        glAttachShader(mProgram, fragShader);
        
        // Delete the fragment shader since it is now attached
        // to the program, which will retain a reference to it
        glDeleteShader(fragShader);
    }
    
   // linkProgram();
}
void MarchingCubesRenderer::init(){
  //_texture.createPyroclasticVolume(64, 0.025f);
  _texture.loadRaw3DData("assets/Data/512x512x512x_uint16.raw", 512, 512, 512, TextureDataType::TDT_USHORT);

  //Form multi-face view
  glEnable(GL_CULL_FACE);
  glEnable(GL_DEPTH_TEST);

  GetGLError();
  /////GLSL/////
  programObject.registerShader("shaders/MarchingCubes/TestG80_GS2.glsl", ShaderType::GEOMETRY);
  programObject.registerShader("shaders/MarchingCubes/TestG80_VS.glsl", ShaderType::VERTEX);
  programObject.registerShader("shaders/MarchingCubes/TestG80_FS.glsl", ShaderType::FRAGMENT);
  programObject.compileShaders();
  programObject.linkShaders();
  programObject.bind();

  GetGLError();
  glGenTextures(1, &(this->edgeTableTex));
  glActiveTexture(GL_TEXTURE1);
  GetGLError();

  GetGLError();
  glBindTexture(GL_TEXTURE_2D, this->edgeTableTex);
  GetGLError();
  //Integer textures must use nearest filtering mode
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  GetGLError();
  //We create an integer texture with new GL_EXT_texture_integer formats
  glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, 256, 1, 0, GL_RED_INTEGER, GL_INT, &edgeTable);

  GetGLError();

  //Triangle Table texture//
  //This texture store the vertex index list for 
  //generating the triangles of each configurations.
  glGenTextures(1, &(this->triTableTex));
  glActiveTexture(GL_TEXTURE2);

  glBindTexture(GL_TEXTURE_2D, this->triTableTex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, 16, 256, 0, GL_RED_INTEGER, GL_INT, &triTable);


  GetGLError();
  //Datafield//
  //Store the volume data to polygonise
  glGenTextures(3, (this->dataFieldTex));

  glActiveTexture(GL_TEXTURE0);
  //glEnable(GL_TEXTURE_3D);
  glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[0]);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  //Generate a distance field to the center of the cube
  dataField[0] = new float[dataSize.x*dataSize.y*dataSize.z];
  for (int k = 0; k < dataSize.z; k++)
  for (int j = 0; j < dataSize.y; j++)
  for (int i = 0; i < dataSize.x; i++){
    float d = distance(vec3(i, j, k), vec3(dataSize.x / 2, dataSize.y / 2, dataSize.z / 2)) / (float)(dataSize.length()*0.4);
    dataField[0][i + j*dataSize.x + k*dataSize.x*dataSize.y] = d;//+(rand()%100-50)/200.0f*d;
  }

  glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, dataSize.x, dataSize.y, dataSize.z, 0, GL_RED, GL_FLOAT, dataField[0]);

  GetGLError();

  //Datafield Perturbated//
  dataField[1] = new float[dataSize.x*dataSize.y*dataSize.z];
  //perturb
  for (int k = 0; k < dataSize.z; k++)
  for (int j = 0; j < dataSize.y; j++)
  for (int i = 0; i < dataSize.x; i++){
    float d = dataField[0][i + j*dataSize.x + k*dataSize.x*dataSize.y];
    dataField[1][i + j*dataSize.x + k*dataSize.x*dataSize.y] = d + (rand() % 100 - 50) / 100.0f*d;
  }

  //Smooth
  for (int l = 0; l < 4; l++)
  for (int k = 1; k < dataSize.z - 1; k++)
  for (int j = 1; j < dataSize.y - 1; j++)
  for (int i = 1; i < dataSize.x - 1; i++){
    dataField[1][i + j*dataSize.x + k*dataSize.x*dataSize.y] = (dataField[1][i + 1 + j*dataSize.x + k*dataSize.x*dataSize.y] + dataField[1][i - 1 + j*dataSize.x + k*dataSize.x*dataSize.y] + dataField[1][i + (j + 1)*dataSize.x + k*dataSize.x*dataSize.y] + dataField[1][i + (j - 1)*dataSize.x + k*dataSize.x*dataSize.y] + dataField[1][i + j*dataSize.x + (k + 1)*dataSize.x*dataSize.y] + dataField[1][i + j*dataSize.x + (k - 1)*dataSize.x*dataSize.y]) / 6.0f;
  }

  //Store the volume data to polygonise
  glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[1]);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, dataSize.x, dataSize.y, dataSize.z, 0, GL_RED, GL_FLOAT, dataField[1]);


  GetGLError();
  //Cayley-polynomial//
  dataField[2] = new float[dataSize.x*dataSize.y*dataSize.z];

  for (int k = 0; k < dataSize.z; k++)
  for (int j = 0; j < dataSize.y; j++)
  for (int i = 0; i < dataSize.x; i++){
    float x = 2.0f / dataSize.x*i - 1.0f;
    float y = 2.0f / dataSize.y*j - 1.0f;
    float z = 2.0f / dataSize.z*k - 1.0f;
    dataField[2][i + j*dataSize.x + k*dataSize.x*dataSize.y] = 16.0f*x*y*z + 4.0f*x*x + 4.0f*y*y + 4.0f*z*z - 1.0f;
  }

  glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[2]);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, dataSize.x, dataSize.y, dataSize.z, 0, GL_RED, GL_FLOAT, dataField[2]);

  GetGLError();
  //Set current texture//
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[curData]);

  GetGLError();

  programObject.setUniform("dataFieldTex", 0);
  programObject.setUniform("edgeTableTex", 1);
  programObject.setUniform("triTableTex", 2);

  GetGLError();
  ////Uniforms parameters////
  //Initial isolevel
  programObject.setUniform("isoLevel", isolevel);
  //Step in data 3D texture for gradient computation (lighting)
  programObject.setUniform("dataStep", vec3(1.0f / dataSize.x, 1.0f / dataSize.y, 1.0f / dataSize.z));
  GetGLError();

  //Decal for each vertex in a marching cube
  programObject.setUniform("vertDecals[0]", vec3(0.0f, 0.0f, 0.0f));
  programObject.setUniform("vertDecals[1]", vec3(cubeStep.x, 0.0f, 0.0f));
  programObject.setUniform("vertDecals[2]", vec3(cubeStep.x, cubeStep.y, 0.0f));
  programObject.setUniform("vertDecals[3]", vec3(0.0f, cubeStep.y, 0.0f));
  programObject.setUniform("vertDecals[4]", vec3(0.0f, 0.0f, cubeStep.z));
  programObject.setUniform("vertDecals[5]", vec3(cubeStep.x, 0.0f, cubeStep.z));
  programObject.setUniform("vertDecals[6]", vec3(cubeStep.x, cubeStep.y, cubeStep.z));
  programObject.setUniform("vertDecals[7]", vec3(0.0f, cubeStep.y, cubeStep.z));
  programObject.setUniform("vertDecals[0]", vec3(0.0f, 0.0f, 0.0f));
  GetGLError();
 



  ////////////////////////////////////////////////////////////////////////////////////////////
  ///////Two others versions of the program////////
  //Geometry Shader only version (plus VS needed)//
  //Program object creation

  ////shaders loading////
  //programObjectGS.registerShader("shaders/MarchingCubes/TestG80_GS2.glsl", ShaderType::GEOMETRY);
  //programObjectGS.registerShader("shaders/MarchingCubes/TestG80_VS.glsl", ShaderType::VERTEX);
  //programObjectGS.registerShader("shaders/MarchingCubes/TestG80_FS_Simple.glsl", ShaderType::FRAGMENT);
  //programObjectGS.compileShaders();
  //programObjectGS.linkShaders();
  //programObjectGS.bind();
  //GetGLError();

  ////Samplers assignment///
  //programObjectGS.setUniform("dataFieldTex", 0);
  //programObjectGS.setUniform("edgeTableTex", 1);
  //programObjectGS.setUniform("triTableTex", 2);

  GetGLError();
  ////Uniforms parameters////
  //Initial isolevel
  //programObjectGS.setUniform("isolevel", isolevel);
  //Decal for each vertex in a marching cube
  //programObjectGS.setUniform("vertDecals[0]", vec3(0.0f, 0.0f, 0.0f));
  //programObjectGS.setUniform("vertDecals[1]", vec3(cubeStep.x, 0.0f, 0.0f));
  //programObjectGS.setUniform("vertDecals[2]", vec3(cubeStep.x, cubeStep.y, 0.0f));
  //programObjectGS.setUniform("vertDecals[3]", vec3(0.0f, cubeStep.y, 0.0f));
  //programObjectGS.setUniform("vertDecals[4]", vec3(0.0f, 0.0f, cubeStep.z));
  //programObjectGS.setUniform("vertDecals[5]", vec3(cubeStep.x, 0.0f, cubeStep.z));
  //programObjectGS.setUniform("vertDecals[6]", vec3(cubeStep.x, cubeStep.y, cubeStep.z));
  //programObjectGS.setUniform("vertDecals[7]", vec3(0.0f, cubeStep.y, cubeStep.z));
  /////

  GetGLError();
  //Fragment Shader only version for software marching cubes lighting//
  //Program object creation

  //Vertex Shader for software MC
  //programObjectFS.registerShader("shaders/MarchingCubes/TestG80_VS2.glsl", ShaderType::VERTEX);
  //programObjectFS.registerShader("shaders/MarchingCubes/TestG80_FS.glsl", ShaderType::FRAGMENT);
  //programObjectFS.setAttributeLocations(Mesh::getShaderAttributeLocations());//Not needed when they are in the shader
  //programObjectFS.compileShaders();
  //programObjectFS.linkShaders();
  //programObjectFS.bind();
  //programObjectFS.setUniform("dataFieldTex", 0);

  //Step in data 3D texture for gradient computation (lighting)
  //programObjectFS.setUniform("dataStep", vec3(1.0f / dataSize.x, 1.0f / dataSize.y, 1.0f / dataSize.z));

  GetGLError();


  //////Grid data construction
  _meshGS->createPointGrid(Vector3(cubeSize.x, cubeSize.y, cubeSize.z));
  _meshGS->bindAttributesToVAO();

  /*
  //Linear Walk
  gridData = new float[(int)(cubeSize.x*cubeSize.y*cubeSize.z * 3)];
  int ii = 0;
  for (float k = -1; k < 1.0f; k += cubeStep.z)
  for (float j = -1; j < 1.0f; j += cubeStep.y)
  for (float i = -1; i < 1.0f; i += cubeStep.x){
    gridData[ii] = i;
    gridData[ii + 1] = j;
    gridData[ii + 2] = k;

    ii += 3;
  }

  //VBO configuration for marching grid linear walk
  glGenBuffers(1, &gridDataBuffId);
  glBindBuffer(GL_ARRAY_BUFFER, gridDataBuffId);
  glBufferData(GL_ARRAY_BUFFER, cubeSize.x*cubeSize.y*cubeSize.z * 3 * 4, gridData, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  GetGLError();
  //Swizzled Walk 
  int n = 0;
  swizzledWalk(n, gridData, ivec3(0, 0, 0), ivec3(cubeSize.x, cubeSize.y, cubeSize.z), cubeSize);


  //VBO configuration for marching grid Swizzled walk
  glGenBuffers(1, &gridDataSwizzledBuffId);
  glBindBuffer(GL_ARRAY_BUFFER, gridDataSwizzledBuffId);
  glBufferData(GL_ARRAY_BUFFER, cubeSize.x*cubeSize.y*cubeSize.z * 3 * 4, gridData, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  */
  GetGLError();


  _mesh->createCube();
  _mesh->bindAttributesToVAO();
}
void MarchingCubesRenderer::draw()
{
	//States setting
	//glEnable(GL_DEPTH_TEST);
	//glDisable(GL_ALPHA_TEST);

  /*
  vec3 eye = vec3(0, 0, 3);
  vec3 up(0, 1, 0); vec3 target(0, 0, 0);
  mat4 mv =glm::lookAt(eye, target, up);

	//Activate modelview
  mv = mv * glm::rotate(GLFWTime::getCurrentTime()*0.5f, vec3(0, 1, 0));
  //mv = glm::rotate(this->viewOrient.y * 10, vec3(0, 1, 0));

  Vector2 size = RenderManager::getInstance().getFramebufferSize();
  float aspect = size.x / size.y;

  float n = 0.01f;
  float f = 100.0f;
  float fieldOfView = 0.7f;// 1.74532925f;//100 degrees

  mat4 projection = glm::perspective(fieldOfView, aspect, n, f);

  mat4 mvp = projection*mv;

  */
  mat4 m = glm::rotate(GLFWTime::getCurrentTime()*0.5f, vec3(0, 1, 0));
  //FROM RENDERER
  Camera& cam = RenderManager::getInstance().getMainCamera();
  mat4 view = cam.getModelview();
  mat4 proj = cam.getProjection();
  mat4 mv = view *m;
  mat4 mvp = proj * mv;

  GetGLError();
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[curData]);
  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, this->edgeTableTex);
  glActiveTexture(GL_TEXTURE2);
  glBindTexture(GL_TEXTURE_2D, this->triTableTex);
  
  GetGLError();

  isolevel = (sin(GLFWTime::getCurrentTime() * 1.5f) + 1.0f) * 0.02f + 0.45f;
  //isolevel = (sin(GLFWTime::getCurrentTime() * 0.5f) + 1.0f) * 0.2f + 0.4f;
  //printf("%3.4f\n", isolevel);

  if(mode != 0){
		if(mode==1){
			//Shader program binding

      programObject.bind();


      _texture.bindToChannel(0);
      programObject.setUniform("dataFieldTex", 0);
      programObject.setUniform("edgeTableTex", 1);
      programObject.setUniform("triTableTex", 2);
			programObject.setUniform("isolevel", isolevel); 
      programObject.setUniform("mvp", mvp);
      programObject.setUniform("ModelViewProjection", mvp);
      //Decal for each vertex in a marching cube
      programObject.setUniform("vertDecals[0]", vec3(0.0f, 0.0f, 0.0f));
      programObject.setUniform("vertDecals[1]", vec3(cubeStep.x, 0.0f, 0.0f));
      programObject.setUniform("vertDecals[2]", vec3(cubeStep.x, cubeStep.y, 0.0f));
      programObject.setUniform("vertDecals[3]", vec3(0.0f, cubeStep.y, 0.0f));
      programObject.setUniform("vertDecals[4]", vec3(0.0f, 0.0f, cubeStep.z));
      programObject.setUniform("vertDecals[5]", vec3(cubeStep.x, 0.0f, cubeStep.z));
      programObject.setUniform("vertDecals[6]", vec3(cubeStep.x, cubeStep.y, cubeStep.z));
      programObject.setUniform("vertDecals[7]", vec3(0.0f, cubeStep.y, cubeStep.z));
      programObject.setUniform("vertDecals[0]", vec3(0.0f, 0.0f, 0.0f));
		}else{
			//Shader program binding
      programObjectGS.bind();
      programObjectGS.setUniform("dataFieldTex", 0);
      programObjectGS.setUniform("edgeTableTex", 1);
      programObjectGS.setUniform("triTableTex", 2);
      programObjectGS.setUniform("isolevel", isolevel);
      programObjectGS.setUniform("mvp", mvp);
      programObjectGS.setUniform("ModelViewProjection", mvp);
		}	

		//glEnable(GL_LIGHTING);

		//Switch to wireframe or solid rendering mode
		//if(wireframe)
		//	glPolygonMode(GL_FRONT_AND_BACK , GL_LINE );
		//else
		//	glPolygonMode(GL_FRONT_AND_BACK , GL_FILL );


    _meshGS->drawBuffers();
   
  	}else{
      //THIS IS SOFTWARE MARCHING CUBES
  		programObjectFS.bind();
      glActiveTexture(GL_TEXTURE0 );
      glBindTexture(GL_TEXTURE_3D, this->dataFieldTex[curData]);
      programObjectFS.setUniform("dataFieldTex", 0);
      programObjectFS.setUniform("mvp", mvp);
      programObjectFS.setUniform("ModelViewProjection", mvp);
      programObjectFS.setUniform("ModelView", mv);
      GetGLError();
  		RenderMarchCube(dataField[curData], ivec3(128,128,128), ivec3(cubeSize.x, cubeSize.y, cubeSize.z), isolevel);
      GetGLError();
      programObjectFS.unbind();
  	}
  }
//Software marching cubes
//VERY far to be optimal !
void MarchingCubesRenderer::RenderMarchCube(float *data, ivec3 size, ivec3 gridsize, float isolevel){
  vec3 gridStep = vec3(2.0, 2.0, 2.0) / vec3(gridsize.x, gridsize.y, gridsize.z);

  ivec3 dataGridStep = size / gridsize;

  vec3 *triangles = new vec3[16];
  
  std::vector<Vector3>& positions = _mesh->getPositionVector();
  positions.clear();

  for (int k = 0; k < gridsize.z - 1; k++)
  for (int j = 0; j < gridsize.y - 1; j++)
  for (int i = 0; i < gridsize.x - 1; i++){
    GridCell cell;
    vec3 vcurf(i, j, k);
    ivec3 vcuri(i, j, k);

    cell.pos[0] = vcurf*gridStep - 1.0f;
    ivec3 valPos0 = vcuri*dataGridStep;
    cell.val[0] = data[valPos0.x + valPos0.y*size.x + valPos0.z*size.x*size.y];

    ivec3 valPos;

    cell.pos[1] = cell.pos[0] + vec3(gridStep.x, 0, 0);
    if (i == gridsize.x - 1)
      valPos = valPos0;
    else
      valPos = valPos0 + ivec3(dataGridStep.x, 0, 0);
    cell.val[1] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[2] = cell.pos[0] + vec3(gridStep.x, gridStep.y, 0);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, j == gridsize.y - 1 ? 0 : dataGridStep.y, 0);
    cell.val[2] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[3] = cell.pos[0] + vec3(0, gridStep.y, 0);
    valPos = valPos0 + ivec3(0, j == gridsize.y - 1 ? 0 : dataGridStep.y, 0);
    cell.val[3] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    cell.pos[4] = cell.pos[0] + vec3(0, 0, gridStep.z);
    valPos = valPos0 + ivec3(0, 0, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[4] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    cell.pos[5] = cell.pos[0] + vec3(gridStep.x, 0, gridStep.z);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, 0, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[5] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[6] = cell.pos[0] + vec3(gridStep.x, gridStep.y, gridStep.z);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, j == gridsize.y - 1 ? 0 : dataGridStep.y, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[6] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[7] = cell.pos[0] + vec3(0, gridStep.y, gridStep.z);
    valPos = valPos0 + ivec3(0, j == gridsize.y - 1 ? 0 : dataGridStep.y, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[7] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    int numvert = Polygonise(cell, isolevel, triangles);

    //Put the triangles into the mesh
    for (int n = 0; n < numvert; n++){
      positions.push_back(Vector3(triangles[n].x, triangles[n].y, triangles[n].z));
    }


  }
  if (positions.empty() == false)
  {
    GetGLError();
    _mesh->constructBuffer();
    GetGLError();
    _mesh->drawBuffers();
    GetGLError();
  }
}
Exemple #19
0
static int GenerateShaders(std::vector<AutoGLProgram> *blend_programs) {
  // Limits: GL_MAX_VARYING_COMPONENTS, GL_MAX_TEXTURE_IMAGE_UNITS,
  // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
  // clang-format off
  const GLchar *shader_preamble = "#version 300 es\n#define LAYER_COUNT ";

  const GLchar *vertex_shader_source =
"\n"
"precision mediump int;                                                     \n"
"uniform vec4 uViewport;                                                    \n"
"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
"uniform vec4 uLayerCrop[LAYER_COUNT];                                      \n"
"in vec2 vPosition;                                                         \n"
"in vec2 vTexCoords;                                                        \n"
"out vec2 fTexCoords[LAYER_COUNT];                                          \n"
"void main() {                                                              \n"
"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
"    fTexCoords[i] = (uLayerCrop[i].xy + vTexCoords * uLayerCrop[i].zw) /   \n"
"                     vec2(textureSize(uLayerTextures[i], 0));              \n"
"  }                                                                        \n"
"  vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;           \n"
"  gl_Position = vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);    \n"
"}                                                                          \n";

  const GLchar *fragment_shader_source =
"\n"
"precision mediump float;                                                   \n"
"uniform sampler2D uLayerTextures[LAYER_COUNT];                             \n"
"uniform float uLayerAlpha[LAYER_COUNT];                                    \n"
"in vec2 fTexCoords[LAYER_COUNT];                                           \n"
"out vec4 oFragColor;                                                       \n"
"void main() {                                                              \n"
"  vec3 color = vec3(0.0, 0.0, 0.0);                                        \n"
"  float alphaCover = 1.0;                                                  \n"
"  for (int i = 0; i < LAYER_COUNT; i++) {                                  \n"
"    vec4 texSample = texture(uLayerTextures[i], fTexCoords[i]);            \n"
"    float a = texSample.a * uLayerAlpha[i];                                \n"
"    color += a * alphaCover * texSample.rgb;                               \n"
"    alphaCover *= 1.0 - a;                                                 \n"
"    if (alphaCover <= 0.5/255.0)                                           \n"
"      break;                                                               \n"
"  }                                                                        \n"
"  oFragColor = vec4(color, 1.0 - alphaCover);                              \n"
"}                                                                          \n";
  // clang-format on

  int i, ret = 1;
  GLint max_texture_images, status;
  AutoGLShader vertex_shader, fragment_shader;
  AutoGLProgram program;
  std::string shader_log;

  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_images);

  for (i = 1; i <= max_texture_images; i++) {
    std::ostringstream layer_count_formatter;
    layer_count_formatter << i;
    std::string layer_count(layer_count_formatter.str());
    const GLchar *shader_sources[3] = {shader_preamble, layer_count.c_str(),
                                       NULL};

    shader_sources[2] = vertex_shader_source;
    vertex_shader = CompileAndCheckShader(GL_VERTEX_SHADER, 3, shader_sources,
                                          ret ? &shader_log : NULL);
    if (!vertex_shader.get()) {
      if (ret)
        ALOGE("Failed to make vertex shader:\n%s", shader_log.c_str());
      break;
    }

    shader_sources[2] = fragment_shader_source;
    fragment_shader = CompileAndCheckShader(
        GL_FRAGMENT_SHADER, 3, shader_sources, ret ? &shader_log : NULL);
    if (!fragment_shader.get()) {
      if (ret)
        ALOGE("Failed to make fragment shader:\n%s", shader_log.c_str());
      break;
    }

    program = AutoGLProgram(glCreateProgram());
    if (!program.get()) {
      if (ret)
        ALOGE("Failed to create program %s", GetGLError());
      break;
    }

    glAttachShader(program.get(), vertex_shader.get());
    glAttachShader(program.get(), fragment_shader.get());
    glBindAttribLocation(program.get(), 0, "vPosition");
    glBindAttribLocation(program.get(), 1, "vTexCoords");
    glLinkProgram(program.get());
    glDetachShader(program.get(), vertex_shader.get());
    glDetachShader(program.get(), fragment_shader.get());

    glGetProgramiv(program.get(), GL_LINK_STATUS, &status);
    if (!status) {
      if (ret) {
        GLint log_length;
        glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &log_length);
        std::string program_log(log_length, ' ');
        glGetProgramInfoLog(program.get(), log_length, NULL, &program_log[0]);
        ALOGE("Failed to link program: \n%s", program_log.c_str());
      }
      break;
    }

    ret = 0;
    blend_programs->emplace_back(std::move(program));
  }

  return ret;
}
 void RocketRenderInterface::bindTexture(uint32_t i_geometry_internal) const {
     glActiveTexture(GL_TEXTURE0);
     GetGLError();
     glBindTexture(GL_TEXTURE_2D, _tex_id[i_geometry_internal]);
     GetGLError();
 }
  // Called by Rocket when it wants to compile geometry it believes will be 
  // static for the forseeable future.		
  Rocket::Core::CompiledGeometryHandle RocketRenderInterface::CompileGeometry(
    Rocket::Core::Vertex* vertices, int num_vertices, int* indices, 
    int num_indices, Rocket::Core::TextureHandle texture) {

    //For now don't compile anything
    //return (Rocket::Core::CompiledGeometryHandle) NULL;

    unsigned int handle = (unsigned int)_vao.size()+1;
    unsigned int new_vao, new_ibo, new_vbo;


    std::vector<unsigned int> ind(num_indices);
    std::vector<float> verts(num_vertices*2);
    std::vector<float> colors(num_vertices*4);
    std::vector<float> texCoords(num_vertices*2);
    for(int i = 0; i < num_indices; i++) {
      ind[i] = static_cast<unsigned int>(indices[i]);
    }

    for(int i = 0; i < num_vertices; i++) {
      int vidx = 2*i;
      verts[vidx] = vertices[i].position.x;
      verts[vidx + 1] = vertices[i].position.y;

      int cidx = 4*i;
      colors[cidx + 0] = vertices[i].colour.red/255.0f;
      colors[cidx + 1] = vertices[i].colour.green/255.0f;
      colors[cidx + 2] = vertices[i].colour.blue/255.0f;
      colors[cidx + 3] = vertices[i].colour.alpha/255.0f;

      texCoords[vidx] = vertices[i].tex_coord.x;
      texCoords[vidx + 1] = vertices[i].tex_coord.y;
    }

    glGenVertexArrays(1, &new_vao);
    glBindVertexArray(new_vao);

    GetGLError();
    glGenBuffers(1, &new_ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, new_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 
      sizeof(unsigned int)*ind.size(),&ind[0], GL_STATIC_DRAW);
    GetGLError();

    glGenBuffers(1, &new_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, new_vbo);
    glBufferData(GL_ARRAY_BUFFER, 
      (verts.size()+colors.size()+texCoords.size())*sizeof(float), NULL, 
      GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*verts.size(), &verts[0]);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*verts.size(), 
      sizeof(float)*colors.size(), &colors[0]);
    GetGLError();

   if(texture > 0) {
      // Load in the textured gui shader
      glBufferSubData(GL_ARRAY_BUFFER, 
        sizeof(float)*(verts.size()+colors.size()), 
        sizeof(float)*texCoords.size(), &texCoords[0]);
      GetGLError();
      setVertexAttribPointerF(Vertex::LocationSlot::POSITION, 2, GL_FLOAT,
        GL_FALSE, 0, BUFFER_OFFSET(0));
      setVertexAttribPointerF(Vertex::LocationSlot::COLOR, 4, GL_FLOAT, 
        GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*verts.size()));
      setVertexAttribPointerF(Vertex::LocationSlot::UV, 2, GL_FLOAT, 
        GL_FALSE, 0, 
        BUFFER_OFFSET(sizeof(float)*(verts.size()+colors.size())));
      _shader_types.push_back(RS_T_WITH_TEXTURE);
    } else {
      _shader_types.push_back(RS_T_NO_TEXTURE);
      setVertexAttribPointerF(Vertex::LocationSlot::POSITION, 2, GL_FLOAT,
        GL_FALSE, 0, BUFFER_OFFSET(0));
      setVertexAttribPointerF(Vertex::LocationSlot::COLOR, 4, GL_FLOAT, 
        GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*verts.size()));
    }

    // Now store away the indices to the geometry objects
    _vao.push_back(new_vao);
    _ibo.push_back(new_ibo);
    _vbo.push_back(new_vbo);
    _index_size.push_back((unsigned int)ind.size());
    _tex_id.push_back(static_cast<unsigned int>(texture));

    // Unbind the VAO just in case anyone makes changes to it.
    glBindVertexArray(0);
    
//    std::cout << "Compiled libRocket geometry " << new_ibo << " "
//    << new_vbo << " " << new_vao << std::endl;

    return handle;
  }