如何在 glDrawPixels 中使用 Eigen

问题描述 投票:0回答:0

我在光栅化中有一个矢量

std::vector<Eigen::Vector3f> frameBuffer
,我想在
glDrawPixels()
中使用它。

光栅化.h

class Rasterization {
 public:
  Rasterization(int w, int h);
  void clear();
  void drawTriangle(Triangle& triangle);
  void drawLine(Eigen::Vector3f begin, Eigen::Vector3f end);
  void setPixel(const Eigen::Vector3f& point, const Eigen::Vector3f& color);
  std::vector<float>& frameBuffer() { return frame_buffer; }
  Model model;
  int width, height;
 private:
  std::vector<float> frame_buffer;  // rgb
  std::vector<float> depth_buffer;  // z-buffer
  
};

和 Rasterization.cpp

LRenderer::Rasterization::Rasterization(int w, int h) : width(w), height(h) {
  frame_buffer.resize(w * h * 3);
  depth_buffer.resize(w * h);
}
void LRenderer::Rasterization::clear() {
  std::fill(frame_buffer.begin(), frame_buffer.end(), 0);
  std::fill(depth_buffer.begin(), depth_buffer.end(), 1);
}
void LRenderer::Rasterization::setPixel(const Eigen::Vector3f& point,
                                        const Eigen::Vector3f& color) {
  if (point.x() < 0 || point.x() >= width || point.y() < 0 ||
      point.y() >= height)
    return;
  auto ind = (height - 1 - point.y()) * width + point.x();
  frame_buffer[ind * 3] = color.x();
  frame_buffer[ind * 3 + 1] = color.y();
  frame_buffer[ind * 3 + 2] = color.z();
}

main.cpp

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <imgui_impl_opengl3.h>

#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>

// include other .h files

void WindowsInit(int width, int height, std::string title) {
  glfwInit();
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  Windows = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
  glfwMakeContextCurrent(Windows);
  glfwSwapInterval(0);
}

int main(){
  LRenderer::PipeLine pipeline(700, 700);
  pipeline.obj_path = "./models/spot/spot_triangulated_good.obj";
  pipeline.Init();

  LRenderer::Triangle tri;
  tri[0].position = Eigen::Vector4f(-0.5, -0.5, 0, 1);
  tri[1].position = Eigen::Vector4f(0.5, -0.5, 0, 1);
  tri[2].position = Eigen::Vector4f(0,0.5,0, 1);
  
  int key = 0;

  WindowsInit(700, 700, "LRenderer");

  if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
  }

  while (key != 27) {
    pipeline.draw(tri);

    cv::Mat image(700, 700, CV_32FC3, pipeline.raster.frameBuffer().data());
    image.convertTo(image, CV_8UC3, 1.0f);
    cv::imshow("image", image);
    key = cv::waitKey(10);
  }
  
  while (!glfwWindowShouldClose(Windows)) {
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    pipeline.raster.clear();
    pipeline.draw(tri);
    auto pixel = pipeline.raster.frameBuffer().data();
    glDrawPixels(700, 700, GL_RGB, GL_FLOAT,
                 pipeline.raster.frameBuffer().data());
    glfwSwapBuffers(Windows);
    glfwPollEvents();
  }
  return 0;
}

pipeline
只包含类光栅化以贡献所有管道。

像这样,

glDrawPixels(700,700,  GL_RGB, GL_FLOAT, frameBuffer.data());
,但是不行。如果我将 frameBuffer 更改为
std::vector<float>
,它也不起作用。这意味着窗户都是黑色的,没有任何图像。但是我用的是OpenCV
cv::mat
,两者都可以成功。

左边是opengl,右边是opencv

期望glDrawPixels可以像opencv一样显示图像

opencv opengl eigen gldrawpixels
© www.soinside.com 2019 - 2024. All rights reserved.