use opengl context for rendering

This commit is contained in:
frank 2021-07-02 22:51:59 -04:00
parent a482fa0a80
commit af5b438f7e
6 changed files with 102 additions and 17 deletions

View File

@ -37,7 +37,7 @@
{
"json-save": true,
"json-save-directory": "local/scans",
"barcode": "1703543090000",
"barcode": "",
"capture-device": "/dev/video0"
},
"api":

@ -1 +1 @@
Subproject commit 17adaed169c40536cb9b25425c64712b1d0f74d1
Subproject commit 569e203409993ea1d34bff910b80f72adb47b690

View File

@ -47,8 +47,54 @@ Pudding::Pudding()
log(message.str());
/* initialize a zbar image scanner for reading barcodes of any format */
image_scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1);
/* use sdl context for now */
load_sdl_context();
/* use gl context so we can draw 3D pudding */
load_gl_context();
}
void Pudding::load_gl_context()
{
super::load_gl_context();
/* Allocate a vertex array object, bind it as current, doesn't need to be a member var because the same one is always bound */
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
/* 2D vertices for the video capture texture that are a single plane spanning the screen */
std::array<glm::vec2, 6> camera_vertices = {
{
{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f},
{1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f}
}};
/* UV map for mapping video capture texture to video capture vertices */
std::array<glm::vec2, 6> camera_uv = {
{
{0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f},
{1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f}
}};
/* generate one vertex buffer object to hold the camera texture and UV vertices */
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
/* allocate space for vertices and UV, copy vertices in at initialization */
GLsizeiptr vbo_size = (camera_vertices.size() + camera_uv.size()) * sizeof(glm::vec2);
glBufferData(GL_ARRAY_BUFFER, vbo_size, camera_vertices.data(), GL_STATIC_DRAW);
/* specify the location and data format of the vertex attributes as consecutive 2D float coords */
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
/* enable index 0 on currently bound VAO */
glEnableVertexAttribArray(0);
/* copy UV data into the VBO, offset to after the vertex data */
glBufferSubData(GL_ARRAY_BUFFER, camera_vertices.size() * sizeof(glm::vec2), camera_uv.size() * sizeof(glm::vec2), camera_uv.data());
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid*>(camera_vertices.size() * sizeof(glm::vec2)));
glEnableVertexAttribArray(1);
GLuint vertex_shader = load_shader("src/flat.vert", GL_VERTEX_SHADER);
GLuint fragment_shader = load_shader("src/flat.frag", GL_FRAGMENT_SHADER);
world_program = glCreateProgram();
glAttachShader(world_program, vertex_shader);
glAttachShader(world_program, fragment_shader);
glBindAttribLocation(world_program, 0, "in_Position");
glBindAttribLocation(world_program, 1, "vertexUV");
link_shader(world_program);
/* generate the texture that will store the video frame */
glGenTextures(1, &video_capture_texture_id);
log_gl_errors();
}
/* Respond to command events */
@ -97,7 +143,8 @@ void Pudding::add_item(const std::string& upc)
incorporate_best_buy_api(item);
}
items.push_back(item);
increment_item_index();
/* set item index to end so newest item will display */
current_item_index = items.size() - 1;
}
/* Look for item upc in the Open Food API, and use the result to fill out item properties if found
@ -390,22 +437,37 @@ void Pudding::update()
SDL_RenderCopyF(get_renderer(), get_current_item().get_active_image_texture().get(), nullptr, &item_box);
video_box.set_left(get_window_box().get_center_x(), true);
}
/* draw the camera to the right half of the screen if the camera has been opened */
/* draw the camera if the camera has been opened, fullscreen if there aren't any items, or on the right otherwise */
if (capture.isOpened())
{
capture.read(capture_frame);
if (!capture_frame.empty())
{
/* convert opencv matrix to sdl texture */
SDL_Texture* texture = SDL_CreateTexture(
get_renderer(), SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STATIC, capture_frame.cols, capture_frame.rows);
SDL_UpdateTexture(texture, nullptr, static_cast<void*>(capture_frame.data), capture_frame.step1());
SDL_RenderCopyF(get_renderer(), texture, nullptr, &video_box);
SDL_DestroyTexture(texture);
/* scan with zbar */
cv::Mat gray;
cv::cvtColor(capture_frame, gray, cv::COLOR_BGR2GRAY);
zbar::Image query_image(gray.cols, gray.rows, "Y800", static_cast<void*>(gray.data), gray.cols * gray.rows);
// SDL_Texture* texture = SDL_CreateTexture(
// get_renderer(), SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STATIC, capture_frame.cols, capture_frame.rows);
// SDL_UpdateTexture(texture, nullptr, static_cast<void*>(capture_frame.data), capture_frame.step1());
// SDL_RenderCopyF(get_renderer(), texture, nullptr, &video_box);
// SDL_DestroyTexture(texture);
glUseProgram(world_program);
/* rotate the opencv matrix 180 to work with opengl coords */
cv::flip(capture_frame, capture_frame, -1);
/* bind texture to GLSL sampler */
GLint base_texture_location = glGetUniformLocation(world_program, "baseTexture");
glUniform1i(base_texture_location, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, video_capture_texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/* convert opencv matrix to GL texture */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, capture_frame.cols, capture_frame.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, capture_frame.ptr());
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(get_window());
log_gl_errors();
/* convert to gray and scan with zbar */
cv::cvtColor(capture_frame, capture_frame, cv::COLOR_BGR2GRAY);
zbar::Image query_image(capture_frame.cols, capture_frame.rows, "Y800", static_cast<void*>(capture_frame.data),
capture_frame.cols * capture_frame.rows);
int result = image_scanner.scan(query_image);
if (result > 0)
{
@ -414,8 +476,8 @@ void Pudding::update()
std::stringstream message;
message << "camera scanned " << symbol->get_type_name() << " symbol " << symbol->get_data();
log(message.str());
current_camera_barcode = symbol->get_data();
current_barcode = current_camera_barcode;
// current_camera_barcode = symbol->get_data();
// current_barcode = current_camera_barcode;
}
}
query_image.set_data(nullptr, 0);

View File

@ -40,7 +40,9 @@ private:
cv::VideoCapture capture;
cv::Mat capture_frame;
zbar::ImageScanner image_scanner;
GLuint vbo, world_program, video_capture_texture_id;
void load_gl_context();
void incorporate_open_food_api(Item&);
void incorporate_nutronix_api(Item&);
void incorporate_edamam_api(Item&);

9
src/flat.frag Normal file
View File

@ -0,0 +1,9 @@
#version 130
in vec2 UV;
uniform sampler2D baseTexture;
void main(void)
{
gl_FragColor = texture(baseTexture, UV);
}

12
src/flat.vert Normal file
View File

@ -0,0 +1,12 @@
#version 130
in vec2 in_Position;
in vec2 vertexUV;
out vec2 UV;
void main(void)
{
gl_Position = vec4(in_Position, 0, 1);
UV = vertexUV;
}