Skip to content

Commit

Permalink
Properly integrate CUDA, remove testCUDA file
Browse files Browse the repository at this point in the history
Also remove c++14 specific code since compiler doesn't support it anymore
  • Loading branch information
nilspin committed Sep 12, 2018
1 parent 88c4c48 commit 0141429
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 165 deletions.
149 changes: 68 additions & 81 deletions Application.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
#define STB_IMAGE_IMPLEMENTATION


#include "cudaHelper.h"
#include "Application.h"
#include "stb_image.h"
#include<fstream>
#include<cuda_runtime_api.h>
#include<cuda.h>
#include<cuda_gl_interop.h>

SDL_Event event;

Application::Application() {
frustum.setFromVectors(vec3(0,0,-1), vec3(0,0,0), vec3(1,0,0), vec3(0,1,0), 5.0, 700.0, 45, 1.3333);
texCoords.resize(640*480);
image1 = stbi_load("assets/T0.png", &DepthWidth, &DepthHeight, &channels, 2);
image2 = stbi_load("assets/T5.png", &DepthWidth, &DepthHeight, &channels, 2);
if(image1 == nullptr) {cout<<"could not read image file!"<<endl; exit(0);}

//put into cuda device buffer
const int DEPTH_SIZE = sizeof(uint16_t)*DepthHeight*DepthWidth;
checkCudaErrors(cudaMalloc((void**)&d_depthInput, DEPTH_SIZE));
checkCudaErrors(cudaMalloc((void**)&d_depthTarget, DEPTH_SIZE));
checkCudaErrors(cudaMemcpy(d_depthInput, image1, DEPTH_SIZE, cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(d_depthTarget, image2, DEPTH_SIZE, cudaMemcpyHostToDevice));
stbi_image_free(image1);
stbi_image_free(image2);


cam.setPosition(glm::vec3(0, 0, 0));
cam.setProjectionMatrix(proj);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
SetupShaders();
SetupBuffers();
SetupDepthTextures();
UploadDepthToTexture(image1, depthTexture1, 0);
UploadDepthToTexture(image2, depthTexture2, 1);
}

Application::~Application() {
checkCudaErrors(cudaGraphicsUnregisterResource(cuda_input_resource));
checkCudaErrors(cudaGraphicsUnregisterResource(cuda_target_resource));
checkCudaErrors(cudaFree(d_depthInput));
checkCudaErrors(cudaFree(d_depthTarget));
}

void Application::run() {
Expand All @@ -34,25 +51,9 @@ void Application::run() {
view = cam.getViewMatrix();
MVP = proj*view*model;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

drawVertexMap->use();

glUniformMatrix4fv(drawVertexMap->uniform("MVP"), 1, false, glm::value_ptr(MVP));

glBindVertexArray(vertexArray);
//inputSource.UploadDepthToTexture();


//first depthMap
glUniform1i(drawVertexMap->uniform("depthTexture"), 0);
glUniform3f(drawVertexMap->uniform("shadeColor"), 1, 0, 0);
glDrawArrays(GL_POINTS, 0, 640*480);
//second depthMap
glUniform1i(drawVertexMap->uniform("depthTexture"), 1);
glUniform3f(drawVertexMap->uniform("shadeColor"), 0, 1, 0);
glDrawArrays(GL_POINTS, 0, 640*480);
//
tracker.Align(d_input, d_inputNormals, d_target, d_targetNormals, d_depthInput, d_depthTarget);
draw(MVP);

mat4 scaleMat = glm::scale(vec3(1000));
mat4 newMVP = proj*view;//*scaleMat
//Draw frustum
Expand All @@ -62,75 +63,61 @@ void Application::run() {
}
}

void Application::draw(const glm::mat4& mvp)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawVertexMap->use();
glUniformMatrix4fv(drawVertexMap->uniform("MVP"), 1, false, glm::value_ptr(mvp));

glBindVertexArray(vertexArray);
glUniform3f(drawVertexMap->uniform("shadeColor"), 1, 0, 0);
glDrawArrays(GL_POINTS, 0, 640*480);

glUniform3f(drawVertexMap->uniform("shadeColor"), 0, 1, 0);
glDrawArrays(GL_POINTS, 0, 640*480);
}

void Application::SetupShaders() {
drawVertexMap = (make_unique<ShaderProgram>());
drawVertexMap = unique_ptr<ShaderProgram>(new ShaderProgram());
drawVertexMap->initFromFiles("shaders/MainShader.vert", "shaders/MainShader.frag");
drawVertexMap->addAttribute("texCoords");
drawVertexMap->addUniform("depthTexture");
drawVertexMap->addAttribute("positions");
drawVertexMap->addUniform("MVP");
drawVertexMap->addUniform("shadeColor");
}

void Application::SetupDepthTextures() {
glGenTextures(1, &depthTexture1);
glBindTexture(GL_TEXTURE_2D, depthTexture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, DepthWidth, DepthHeight, 0, GL_RG, GL_UNSIGNED_BYTE, 0);
//filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//Texture2
glGenTextures(1, &depthTexture2);
glBindTexture(GL_TEXTURE_2D, depthTexture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, DepthWidth, DepthHeight, 0, GL_RG, GL_UNSIGNED_BYTE, 0);
//filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
}


void Application::SetupBuffers() {
//First create array on RAM
for (int i = 0; i < DepthWidth; ++i)
{
for (int j = 0; j < DepthHeight; ++j)
{
texCoords[i * DepthHeight + j] = (glm::vec2(i, j));
}
}

//Create Vertex Array Object
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);

glGenBuffers(1, &texCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, DepthWidth * DepthHeight * sizeof(glm::ivec2), texCoords.data(), GL_STATIC_DRAW);
const uint ARRAY_SIZE = DepthWidth * DepthHeight * sizeof(glm::vec4);
//As we go along register buffers with CUDA as well
glGenBuffers(1, &inputVBO);
glBindBuffer(GL_ARRAY_BUFFER, inputVBO);
glBufferData(GL_ARRAY_BUFFER, ARRAY_SIZE, nullptr, GL_DYNAMIC_DRAW);
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&cuda_input_resource, inputVBO, cudaGraphicsRegisterFlagsNone));
checkCudaErrors(cudaGraphicsMapResources(1, &cuda_input_resource, 0));
size_t returnedBufferSize;
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_input, &returnedBufferSize, cuda_input_resource));
std::cout<<"Allocated input VBO size: "<<returnedBufferSize<<"\n";

glGenBuffers(1, &targetVBO);
glBindBuffer(GL_ARRAY_BUFFER, targetVBO);
glBufferData(GL_ARRAY_BUFFER, ARRAY_SIZE, nullptr, GL_DYNAMIC_DRAW);
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&cuda_target_resource, targetVBO, cudaGraphicsRegisterFlagsNone));
checkCudaErrors(cudaGraphicsMapResources(1, &cuda_target_resource, 0));
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_target, &returnedBufferSize, cuda_target_resource));
std::cout<<"Allocated target VBO size: "<<returnedBufferSize<<"\n";

//Now set up VBOs
checkCudaErrors(cudaMalloc((void**)&d_inputNormals, ARRAY_SIZE));
checkCudaErrors(cudaMalloc((void**)&d_targetNormals, ARRAY_SIZE));
checkCudaErrors(cudaMalloc((void**)&d_correspondence, ARRAY_SIZE));
//Assign attribs
glEnableVertexAttribArray(drawVertexMap->attribute("texCoords"));
glVertexAttribPointer(drawVertexMap->attribute("texCoords"), 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0); //unbind VAO
}

void Application::UploadDepthToTexture(uint8_t* image, int texID, int texUnit) {

glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 640, 480, 0, GL_RG, GL_UNSIGNED_BYTE, image);

}

Application::~Application() {
stbi_image_free(image1);
stbi_image_free(image2);
glEnableVertexAttribArray(drawVertexMap->attribute("positions"));
glVertexAttribPointer(drawVertexMap->attribute("positions"), 4, GL_FLOAT, GL_FALSE, 0, 0);
//glBindVertexArray(0); //unbind VAO
}

void Application::processEvents() {
Expand Down
27 changes: 20 additions & 7 deletions Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ShaderProgram.hpp"
#include "camera.h"
#include "Frustum.h"
#include "CameraTracking.h"

using namespace std;
using namespace glm;
Expand Down Expand Up @@ -37,32 +38,44 @@ class Application
glm::mat4 view = glm::mat4(1);
glm::mat4 proj = glm::perspective(45.0f, 1.3333f, 0.1f, 5000.0f);
glm::mat4 MVP = glm::mat4(1);
glm::mat4 deltaT = glm::mat4(1); //we need to find this each iteration

//Frustum
Frustum frustum;
//Frustum
Frustum frustum;

//Shader
unique_ptr<ShaderProgram> drawVertexMap;

//CameraTracker
CameraTracking tracker;

//Texture & images
GLuint depthTexture1, depthTexture2;
uint8_t *image1=nullptr;
uint8_t *image2=nullptr;

//OpenGL Buffer objects
vector<glm::ivec2> texCoords;
GLuint vertexBuffer;
GLuint texCoordBuffer;
GLuint inputVBO;
GLuint targetVBO;
GLuint vertexArray;


void UploadDepthToTexture(uint8_t*, int, int);
void SetupShaders();
void SetupBuffers();
void SetupDepthTextures();
void processEvents();
void draw(const glm::mat4&);

//CUDA stuff
struct cudaGraphicsResource *cuda_target_resource;
struct cudaGraphicsResource *cuda_input_resource;
//TODO: Do we need this for normals as well?

uint16_t *d_depthInput, *d_depthTarget;
vec4* d_input;
vec4* d_inputNormals;
vec4* d_target;
vec4* d_targetNormals;
vec4* d_correspondence;
};

#endif //APPLICATION_H
26 changes: 14 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#====================
cmake_minimum_required (VERSION 2.8)
PROJECT(ICP_Demo)
cmake_minimum_required (VERSION 3.9)
PROJECT(ICP_Demo LANGUAGES CXX CUDA)

# Useful CMake options for Qt projects
# Useful CMake options
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_FLAGS "-std=c++0x -g")
set (CMAKE_CXX_FLAGS "-fpermissive -fPIC")
set(CMAKE_CXX_FLAGS "-std=c++0x -fpermissive")
set(OpenGL_GL_PREFERENCE "GLVND")

# Search desired Qt packages
Expand All @@ -15,10 +14,10 @@ find_package(OpenGL REQUIRED)
find_package(SDL2 REQUIRED)
find_package(GLEW REQUIRED)
find_package(glm REQUIRED)
find_package(Boost COMPONENTS filesystem REQUIRED)
find_package(Boost COMPONENTS filesystem REQUIRED) #only need this till nvcc starts supporting c++17 compiler

set(INCLUDE_DIRS ${INCLUDE_DIRS} ${CUDA_INCLUDE_DIRECTORIES} ${OPENGL_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(LIBS ${LIBS} ${OPENGL_LIBRARY} ${SDL2_LIBRARIES} ${GLEW_LIBRARIES} ${Boost_LIBRARIES})
set(INCLUDE_DIRS ${INCLUDE_DIRS} ${CUDA_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(LIBS ${LIBS} ${OPENGL_LIBRARY} ${CUDA_LIBRARIES} ${SDL2_LIBRARIES} ${GLEW_LIBRARIES} ${Boost_LIBRARIES})

if(CUDA_FOUND)
# compared to class settings, we let NVidia's FindCUDA CMake detect
Expand All @@ -40,24 +39,27 @@ if(CUDA_FOUND)
# add debugging to CUDA NVCC flags. For NVidia's NSight tools.
set(CUDA_NVCC_FLAGS_DEBUG ${CUDA_NVCC_FLAGS_DEBUG} "-G")

CUDA_ADD_EXECUTABLE(testCUDA testCUDA.cu)
else(CUDA_FOUND)
message("CUDA is not installed on this system.")
endif()

#specify include directory
#include_directories(/usr/include)
include_directories(${CMAKE_SOURCE_DIR})
include_directories(INCLUDE_DIRS ${INCLUDE_DIRS} )
include_directories(INCLUDE_DIRS ${INCLUDE_DIRS})

set(SOURCES DepthMain.cpp camera.cpp Window.cpp Application.cpp prereq.h ShaderProgram.hpp Frustum.cpp camera.h Window.h
Application.h Frustum.h)
Application.h Frustum.h cudaHelper.h CameraTracking.h)

#Compile
add_library(CameraTracking STATIC CameraTracking.cu )
set_target_properties(CameraTracking PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(CameraTracking PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

add_executable(${PROJECT_NAME} ${SOURCES})

#Link all obj files
target_link_libraries(${PROJECT_NAME} ${LIBS} SDL2::SDL2)
target_link_libraries(${PROJECT_NAME} ${LIBS} SDL2::SDL2 CameraTracking)

#Now copy shaders to build directory

Expand Down
44 changes: 43 additions & 1 deletion DepthMain.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,53 @@
#include "Application.h"
#include <memory>
#include <cuda_runtime_api.h>
#include <cuda.h>

using std::cout;
void printCudaDetails();

int main(int argc, char *argv[])
{

//std::unique_ptr<Application> app = std::make_unique<Application>();
std::unique_ptr<Application> app(make_unique<Application>());

printCudaDetails();
std::unique_ptr<Application> app(new Application());
app->run();
return 0;
}

void printCudaDetails() {
int deviceCount = 0;
cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
if (error_id != cudaSuccess) {
cout<<"cudaGetDeviceCount returned "<<static_cast<int>(error_id)<<"\n"
<< cudaGetErrorString(error_id)<<"\n";
cout<<"Result = FAIL\n";
exit(EXIT_FAILURE);
}

// This function call returns 0 if there are no CUDA capable devices.
if (deviceCount == 0) {
cout<<"There are no available device(s) that support CUDA\n";
} else {
cout<<"Detected "<<deviceCount<<" CUDA Capable device(s)\n";
}

int dev, driverVersion = 0, runtimeVersion = 0;

for (dev = 0; dev < deviceCount; ++dev) {
cudaSetDevice(dev);
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);

cout<<"\nDevice: "<<dev<<" "<<deviceProp.name<<"\n";

// Console log
cudaDriverGetVersion(&driverVersion);
cudaRuntimeGetVersion(&runtimeVersion);
cout<<" CUDA Driver Version / Runtime Version "<<driverVersion / 1000<<"."<<(driverVersion % 100) / 10
<<" / "<<runtimeVersion / 1000<<", "<< ((runtimeVersion % 100) / 10)<<"\n",
cout<<" CUDA Capability Major/Minor version number: "<<deviceProp.major<<"."<< deviceProp.minor<<"\n\n";
}
}
2 changes: 1 addition & 1 deletion Frustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Frustum::Frustum(){
glBindVertexArray(frustum);
glGenBuffers(1,&frustumBuffer);

drawFrustum = (std::make_unique<ShaderProgram>());
drawFrustum = (std::unique_ptr<ShaderProgram>(new ShaderProgram()));
drawFrustum->initFromFiles("shaders/drawFrustum.vert", "shaders/drawFrustum.frag");
drawFrustum->addUniform("VP");
drawFrustum->addUniform("frustumColor");
Expand Down
Loading

0 comments on commit 0141429

Please sign in to comment.