OpenGL-入门-BMP像素图glReadPixels(1)实现读取屏幕中间的颜色和获取屏幕上鼠标点击位置的颜色

glReadPixels函数用于从帧缓冲区中读取像素数据。它可以用来获取屏幕上特定位置的像素颜色值或者获取一块区域内的像素数据。下面是该函数的基本语法:

c 复制代码
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *data);

x 和 y:读取区域左下角的像素坐标。

width 和 height:读取区域的宽度和高度。

format:像素数据的格式,可以是 GL_RGBA、GL_RGB、GL_DEPTH_COMPONENT 等等。

type:数据的数据类型,如 GL_UNSIGNED_BYTE、GL_FLOAT 等。

data:存储像素数据的缓冲区。

举个例子,如果你想获取屏幕上位置 (100, 100) 处的像素颜色值,你可以这样使用 glReadPixels:

c 复制代码
GLubyte pixel[3];
glReadPixels(100, 100, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);

这将会把位置 (100, 100) 处的 RGB 像素颜色值存储在 pixel 数组中。

如果你想读取一个区域的像素数据,可以调整 width 和 height 参数的值。

请注意,glReadPixels 函数是一个相对慢的操作,因为它涉及到从显存中读取数据,这可能会在性能方面产生一些影响。在实际应用中,如果需要频繁地读取像素数据,最好考虑使用一些其他的技术来减少性能开销。

标题示例一:实现读取屏幕中间的颜色

cpp 复制代码
//实现读取屏幕中间的颜色
#define WindowWidth 400
#define WindowHeight 400
    
#pragma warning(disable:4996)

#include <GL/glut.h>
#include <iostream>
#include <math.h>

void display() {
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw something on the screen
    glColor3f(1.0, 0.0, 0.0); // Red color
    glBegin(GL_TRIANGLES);
    glVertex2f(-0.5, -0.5);
    glVertex2f(0.5, -0.5);
    glVertex2f(0.0, 0.5);
    glEnd();

    glFlush(); // Ensure all drawing commands are executed
}

void readPixelData() {
    GLint viewport[4]; // Viewport dimensions [x, y, width, height]
    glGetIntegerv(GL_VIEWPORT, viewport); // Get viewport dimensions

    GLubyte pixel[3];
    /*在例子中,GLubyte pixel[3]; 定义了一个长度为3的数组,用来存储从glReadPixels函数中读取到的像素颜色值。由于我们在这个例子中读取的是RGB颜色,所以数组的长度是3,分别用于存储红、绿和蓝三个颜色分量的值。*/
    GLint x = viewport[2] / 2; // X coordinate at the center
    /*
    viewport[2] 表示视口(viewport)的宽度。视口是屏幕上用于显示OpenGL图形的区域。数组索引为 2 的元素存储的就是视口的宽度。viewport[2] / 2 就是将视口的宽度除以 2,从而得到了视口的中心位置的 x 坐标。
    */
    GLint y = viewport[3] / 2; // Y coordinate at the center

    // Invert y-coordinate to match OpenGL's coordinate system
    y = viewport[3] - y - 1;

    glReadBuffer(GL_FRONT); // Set the buffer to read from the front buffer
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);

    printf("Pixel color at center: R=%u, G=%u, B=%u\n", pixel[0], pixel[1], pixel[2]);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("glReadPixels Example");

    glutDisplayFunc(display);
    glutIdleFunc(readPixelData); // Read pixel data after drawing and during idle time


    glutMainLoop();
    return 0;
}

标题示例二:获取屏幕上鼠标点击位置的颜色

cpp 复制代码
#include <GL/glut.h>
#include <iostream>

// 存储窗口大小
int windowWidth = 800;
int windowHeight = 600;

// 存储鼠标点击位置的颜色
GLubyte clickedColor[3] = { 0, 0, 0 };
void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // 绘制渐变色矩形
    glBegin(GL_QUADS);
    
    // 左上角顶点,红色
    glColor3ub(255, 0, 0);
    glVertex2f(-0.5f, 0.5f);
    
    // 右上角顶点,绿色
    glColor3ub(0, 255, 0);
    glVertex2f(0.5f, 0.5f);
    
    // 右下角顶点,蓝色
    glColor3ub(0, 0, 255);
    glVertex2f(0.5f, -0.5f);
    
    // 左下角顶点,黄色
    glColor3ub(255, 255, 0);
    glVertex2f(-0.5f, -0.5f);
    
    glEnd();

    glFlush();
}
//鼠标左键按下并释放时,获取鼠标点击位置的像素颜色,并将该颜色信息显示在控制台中
void mouse(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        GLint viewport[4];
        //这一行代码获取当前窗口的视口信息,并将信息存储在 viewport 数组中。视口包括窗口的位置和尺寸。
        glGetIntegerv(GL_VIEWPORT, viewport);

        // 使用glReadPixels获取点击位置的像素颜色
        glReadPixels(x, viewport[3] - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, clickedColor);
        //viewport[3]表示视口的高度,
        std::cout << "Clicked pixel color: R=" << static_cast<int>(clickedColor[0]) << ", G=" << static_cast<int>(clickedColor[1]) << ", B=" << static_cast<int>(clickedColor[2]) << std::endl;
       
    }
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow("Mouse Click Color Picker");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);

    glutMainLoop();
    return 0;
}
相关推荐
刘好念4 天前
[OpenGL]使用OpenGL实现硬阴影效果
c++·计算机图形学·opengl
闲暇部落5 天前
Android OpenGL ES详解——纹理:纹理过滤GL_NEAREST和GL_LINEAR的区别
opengl·texture·linear·纹理过滤·nearest·邻近过滤·线性过滤
凌云行者6 天前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
凌云行者6 天前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
凌云行者9 天前
OpenGL入门004——使用EBO绘制矩形
c++·cmake·opengl
闲暇部落9 天前
Android OpenGL ES详解——模板Stencil
android·kotlin·opengl·模板测试·stencil·模板缓冲·物体轮廓
凌云行者11 天前
OpenGL入门003——使用Factory设计模式简化渲染流程
c++·cmake·opengl
凌云行者12 天前
OpenGL入门002——顶点着色器和片段着色器
c++·cmake·opengl
闲暇部落13 天前
Android OpenGL ES详解——裁剪Scissor
android·kotlin·opengl·窗口·裁剪·scissor·视口
彭祥.18 天前
点云标注工具开发记录(四)之点云根据类别展示与加速渲染
pyqt·opengl