Interesting
Interesting

Reputation: 49

How to use Eigen in glDrawPixels

I have a vector std::vector<Eigen::Vector3f> frameBuffer in Rasterization, and I want to use it in glDrawPixels().

The Rasterization.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
  
};

And the 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();
}

The 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;
}

The pipeline just include the class Rasterization to contribute the all pipeline.

Like this, glDrawPixels(700,700, GL_RGB, GL_FLOAT, frameBuffer.data());, but it doesn't work. If I change frameBuffer as std::vector<float>, it also doesn't work. That means the windows are all black, no any image. But I use OpenCV cv::mat, both of them can work successful.

The OpenCV result The opengl is left, and the opencv is right.

Expect the glDrawPixels can show the image, like the opencv

Upvotes: 0

Views: 79

Answers (1)

Rabbid76
Rabbid76

Reputation: 210978

You cannot use glDrawPixels in a core profile OpenGL Context (GLFW_OPENGL_COMPAT_PROFILE). glDrawPixels is deprecated. Either use a compatibility OpenGL Context (GLFW_OPENGL_CORE_PROFILE)` or use "modern" OpenGL, including a shader program, a vertex specification and a texture object. How to do this is explained in plenty of tutorials (e.g.: LearnOpenGL) and is too broad for a single StackOverflow answer.

Upvotes: 1

Related Questions