void sendDataToGL() { std::vector<float> lut; int lutSize = mTable->GetNumberOfTuples(); int lutDataSize = lutSize * mTable->GetNumberOfComponents(); lut.resize(lutDataSize); unsigned char* ptr = mTable->GetPointer(0); for (int i = 0; i < lut.size(); ++i) { lut[i] = ((float) *ptr) / 255.0; ++ptr; } glBindTexture(GL_TEXTURE_1D, textureId); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); report_gl_error(); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, lutSize, 0, GL_RGBA, GL_FLOAT, &(*lut.begin())); report_gl_error(); }
void ShaderCallback::addUniformfArray(vtkShaderProgram *program, std::string name, float value) { //Note: Set uniform will fail if the uniform is not present OR active (used inside the program). report_gl_error(); //CX_LOG_DEBUG() << "Adding uniform called: " << name << " with value " << value; if(!program->SetUniform1fv(name.c_str(), 1, &value)) { CX_LOG_ERROR() << "Could not set uniform named " << name; } report_gl_error(); }
void ShaderCallback::test( unsigned long event, void *cbo) { std::cout << " START TEST" << std::endl; if(event == vtkCommand::UpdateShaderEvent) { std::cout << "--- START UpdateShaderEvent" << std::endl; vtkOpenGLHelper *cellBO = reinterpret_cast<vtkOpenGLHelper*>(cbo); report_gl_error(); if(cellBO && cellBO->VAO) { report_gl_error(); vtkShaderProgram *program = cellBO->Program; vtkOpenGLVertexArrayObject *vao = cellBO->VAO; std::cout << "Program is compiled? " << program->GetCompiled() << std::endl; std::cout << "Program is bound? " << program->isBound() << std::endl; std::cout << "IBO index count " << cellBO->IBO->IndexCount << std::endl; report_gl_error(); GLint color_frag_out_index = glGetFragDataLocation(cellBO->Program->GetHandle(), "color"); std::cout << "color index " << color_frag_out_index << std::endl; glBindFragDataLocation(cellBO->Program->GetHandle(), color_frag_out_index, "color"); //setting output of fragment shader std::cout << "ADDING ATTRIBUTE ARRAY" << std::endl; /* vao->Bind(); if (!vao->AddAttributeArray(program, vbo.Get(), "vertexMC", 0, sizeof(float)*3, VTK_FLOAT, 3, false)) { vtkGenericWarningMacro(<< "Error setting 'vertexMC' in shader VAO."); } */ vao->Bind(); //Input color int vec_size = 3; if (!vao->AddAttributeArray( program, //vtkShaderProgram mColorBufferObject.Get(), //vtkOpenGLBufferObject "COLOR_VSIN", //std::string 0, //int (offset) where to start reading g_color_buffer_data, offset != 0 == discard some of the first values sizeof(float)*3, //size_t (stride) If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. VTK_FLOAT, //int (elementType) Specifies the data type of each component in the array vec_size, //int (elementTupleSize) Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. false //bool (normalize) )) { vtkGenericWarningMacro(<< "Error setting 'COLOR' in shader VAO."); }
virtual void bind(int textureUnitIndex) { this->updateTexture(); if (!mAllocated) { std::cout << "error: called bind() on unallocated lut buffer" << std::endl; return; } glActiveTexture(getGLTextureForLut(textureUnitIndex)); this->bindDataToGL(); report_gl_error(); }
virtual void updateTexture() { if (mMTime == mTable->GetMTime()) { return; } mMTime = mTable->GetMTime(); glActiveTexture(GL_TEXTURE6); this->sendDataToGL(); report_gl_error(); }
/**Activate and bind the volume and lut buffers inside the texture units * GL_TEXTURE<2X> and GL_TEXTURE<2X+1>. * Use during RenderInternal() */ virtual void bind(int textureUnitIndex) { this->updateTexture(); if (!mAllocated) { std::cout << "error: called bind() on unallocated volume buffer" << std::endl; return; } glActiveTexture(getGLTextureForVolume(textureUnitIndex)); glBindTexture(GL_TEXTURE_3D, textureId); report_gl_error(); }
/** * @brief ShaderCallback::addArrayToAttributeArray * In the vertex shader there is an in array of vec3 which will contain texture coordinates per uploaded texture. This function populates this array. * @param program The shader program to work with. * @param buffer The buffer containing the texture coordinates. * @param name The name of the array variable in the vertex shader which will point to the texture coordinates. * @param vector_index The place in the */ void ShaderCallback::addArrayToAttributeArray(vtkShaderProgram *program, vtkOpenGLBufferObjectPtr buffer, std::string name, int vector_index) { //-------- //This is information about how the texture coordinates are uploaded. int offset = 0; int vec_size = 3; size_t stride = sizeof(float)*vec_size; //is this correct? was *3; int elementType = GL_FLOAT; //VTK_FLOAT bool normalize = false; //CX_LOG_DEBUG() << "Adding attribute called: " << name << " to vector_index: " << vector_index; //-------- const GLchar *namePtr = static_cast<const GLchar *>(name.c_str()); GLint start_of_vector_index = glGetAttribLocation(program->GetHandle(), namePtr); report_gl_error(); if(start_of_vector_index != -1) { GLint position_in_vector_index = start_of_vector_index + vector_index; buffer->Bind(); glEnableVertexAttribArray(position_in_vector_index); glVertexAttribPointer(position_in_vector_index, vec_size, elementType, normalize, static_cast<GLsizei>(stride), ((char *)NULL + (offset)) ); report_gl_error(); } else { CX_LOG_ERROR() << "Error setting attribute " << name << " with vector_index " << vector_index; } }
/** * @name core_check_gl_error * @brief check's for a gl error and reports it to the platform * @retval NONE */ void core_check_gl_error() { // check the gl error and send it to java to be logged int error_code = glGetError(); if (error_code != 0) { LOG("{core} WARNING: OpenGL error %d", error_code); //check if we should report the error, return early if not. if (error_code == GL_ERROR_OUT_OF_MEMORY) { //does not matter if it is already in the hash, report as unrecoverable and respond report_gl_error(error_code, &gl_errors_hash, true); //use halfsized textures for lower memory footprint set_halfsized_textures(true); } else { //check if error is in the hash, if it is, leave gl_error *error = NULL; HASH_FIND_INT(gl_errors_hash, &error_code, error); if (!error) { report_gl_error(error_code, &gl_errors_hash, false); } } } }
void ShaderCallback::printDebugInfo(vtkOpenGLHelper *OpenGLHelper) { if(!OpenGLHelper) { return; } vtkShaderProgram *program = OpenGLHelper->Program; std::cout << "Program is compiled? " << program->GetCompiled() << std::endl; std::cout << "Program is bound? " << program->isBound() << std::endl; std::cout << "IBO index count " << OpenGLHelper->IBO->IndexCount << std::endl; std::string vertexshader = program->GetVertexShader()->GetSource(); std::cout << "Vertexshader:\n " << vertexshader << std::endl; std::string fragmentshader = program->GetFragmentShader()->GetSource(); std::cout << "Fragmentshader:\n " << fragmentshader << std::endl; report_gl_error(); }
void ShaderCallback::Execute(vtkObject *, unsigned long eventId, void *cbo) { report_gl_error(); vtkOpenGLHelper *OpenGLHelper = reinterpret_cast<vtkOpenGLHelper*>(cbo); if(!OpenGLHelper || !OpenGLHelper->VAO || !OpenGLHelper->Program) { return; } if(eventId == vtkCommand::UpdateShaderEvent) { report_gl_error(); int textures_to_add = this->getNumberOfUploadedTextures(); //Bind fragmentshader output variable // (glsl: vec4) if(textures_to_add != 0) { this->bindFSOutputVariable(OpenGLHelper->Program); } report_gl_error(); //Bind VAO (Vertext Array Object - aka saved input to the vertex shader) OpenGLHelper->VAO->Bind(); report_gl_error(); for(int i=0; i< textures_to_add; ++i) { ShaderItemPtr shaderItem = mShaderItems.at(i); // texture coordinates (glsl: vec3) vtkOpenGLBufferObjectPtr texture_coordinates = shaderItem->mTextureCoordinates; if(texture_coordinates) { if(!texture_coordinates->Bind()) { CX_LOG_WARNING() << "Could not bind texture coordinates"; } this->addArrayToAttributeArray(OpenGLHelper->Program, texture_coordinates, VS_In_Vec3_TextureCoordinate, i); } else { CX_LOG_WARNING() << "NO TEXTURE COORDINATES!"; } report_gl_error(); // 3D texture pointer (glsl: sampler3D) vtkTextureObjectPtr texture = shaderItem->mTexture; if(texture) { texture->Activate(); this->addUniformiArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_3DTexture_Volume, i), texture->GetTextureUnit()); } else { CX_LOG_WARNING() << "NO 3D TEXTURE!"; } report_gl_error(); // 1D texture pointer (glsl: sampler1D) vtkTextureObjectPtr lut = shaderItem->mLUT; if(lut) { lut->Activate(); this->addUniformiArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_1DTexture_LUT, i), lut->GetTextureUnit()); } else { CX_LOG_WARNING() << "NO 1D TEXTURE!"; } report_gl_error(); this->addUniformfArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_Window,i), shaderItem->mWindow); this->addUniformfArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_Level,i), shaderItem->mLevel); this->addUniformfArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_LLR,i), shaderItem->mLLR); this->addUniformfArray(OpenGLHelper->Program, getVectorNameFromName(FS_Uniform_Alpha,i), shaderItem->mAlpha); } } report_gl_error(); }
virtual void updateTexture() { if (mMTime == mTexture->GetMTime()) { return; } mMTime = mTexture->GetMTime(); //vtkgl::ActiveTexture(getGLTextureForVolume(textureUnitIndex)); //TODO is this OK? GLenum size,internalType; boost::uint32_t dimx = mTexture ->GetDimensions( )[0]; boost::uint32_t dimy = mTexture ->GetDimensions( )[1]; boost::uint32_t dimz = mTexture ->GetDimensions( )[2]; mMemorySize = dimx * dimy * dimz; glEnable( GL_TEXTURE_3D ); glBindTexture(GL_TEXTURE_3D, textureId); report_gl_error(); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); switch (mTexture->GetScalarType()) { case VTK_UNSIGNED_CHAR: { size = GL_UNSIGNED_BYTE; internalType = GL_LUMINANCE; } break; //8UI_EXT; break; case VTK_UNSIGNED_SHORT: { size = GL_UNSIGNED_SHORT; internalType = GL_LUMINANCE16; mMemorySize *= 2; } break; //16UI_EXT; break; default: size = 0; internalType = 0; std::cout << "Bit size not supported!" << std::endl; QString dataType(mTexture->GetScalarTypeAsString()); CX_LOG_ERROR() << QString("Attempt to update 3D GL texture from type %1 failed. Only unsigned types supported").arg(dataType); break; } if (mTexture->GetNumberOfScalarComponents()==1) { void* data = mTexture->GetPointData()->GetScalars()->GetVoidPointer(0); glTexImage3D(GL_TEXTURE_3D, 0, internalType, dimx, dimy, dimz, 0, GL_LUMINANCE, size, data); } else if (mTexture->GetNumberOfScalarComponents()==3) { internalType = GL_RGB; void* data = mTexture->GetPointData()->GetScalars()->GetVoidPointer(0); glTexImage3D(GL_TEXTURE_3D, 0, internalType, dimx, dimy, dimz, 0, GL_RGB, size, data); mMemorySize *= 3; } else { std::cout << "unsupported number of image components" << std::endl; } glDisable(GL_TEXTURE_3D); report_gl_error(); }