Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用GTK绘制Pixmap?_C_Gtk3_Cairo_Gdk - Fatal编程技术网

C 如何使用GTK绘制Pixmap?

C 如何使用GTK绘制Pixmap?,c,gtk3,cairo,gdk,C,Gtk3,Cairo,Gdk,使用GTK3,我一直在尝试从内存缓冲区绘制一个Pixmap。我刚刚创建了一个内存缓冲区,并用32位RGBA格式的交替颜色行填充它。我一直在尝试以下功能: gdk_pixbuf_new_from_data(const guchar*data,GdkColorspace colorspace,gboolean has_alpha,int bits_per_sample,int width,int height,int rowstride,GdkPixbufDestroyNotify destroy_

使用GTK3,我一直在尝试从内存缓冲区绘制一个Pixmap。我刚刚创建了一个内存缓冲区,并用32位RGBA格式的交替颜色行填充它。我一直在尝试以下功能:
gdk_pixbuf_new_from_data(const guchar*data,GdkColorspace colorspace,gboolean has_alpha,int bits_per_sample,int width,int height,int rowstride,GdkPixbufDestroyNotify destroy_fn,gpointer destroy_fn_data)

使用这个,我已经能够将内存缓冲区包装到一个
GdkPixbuf*
,但是当我试图用Cairo将pixbuf绘制到屏幕上时,图像似乎失真了

这是我一直在试验的测试程序:

#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

const int WIDTH = 1080;
const int HEIGHT = 720;

GtkWidget* mainWindow;

int currentCol = 0;

uint32_t* framebuffer = NULL;
GdkPixbuf* pixbuf = NULL;


typedef struct _rgbColor {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
    uint8_t alpha;
}rgbColor;


void onWindowDestroy (GtkWidget* object, gpointer user_data) {
    gtk_main_quit();
}

gboolean onTimerTick(gpointer user_data) {
    rgbColor c = {0, 0, 0, 255};
    if (currentCol == 0) {
        c.red = 255;
    }
    if (currentCol == 1) {
        c.green = 255;
    }
    if (currentCol == 2) {
        c.blue = 255;
        currentCol = -1;
    }
    currentCol++;
    fillWithColour(framebuffer, c);

    rgbColor c1 = {0, 0, 255, 255};
    fillEveryInterval(framebuffer, c1, 20);
    gtk_widget_queue_draw(mainWindow);
    return 1;
}

gboolean onDraw(GtkWidget* widget, cairo_t *cr, gpointer user_data) {
    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
    cairo_paint(cr);
    return 0;
}

void fillWithColour(uint32_t* fb, rgbColor c) {
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            encodePixel(fb, c, x, y);
        }
    }
}

void fillEveryInterval(uint32_t* fb, rgbColor c, int interval) {
    for (int y = 1; y < HEIGHT; y += interval) {
        for (int x = 0; x < WIDTH; x++) {
            encodePixel(fb, c, x, y);
        }
    }
}


void encodePixel(uint32_t* fb, rgbColor c, int x, int y) {
    uint32_t r, g, b, a;

    r = c.red;
    g = c.green << 8;
    b = c.blue << 16;
    a = c.alpha << 24;
    
    *(fb + (sizeof(uint32_t)*y+x)) = b | g | r | a;
}

int main() {
    framebuffer = malloc(sizeof(uint32_t)*WIDTH*HEIGHT);
    rgbColor c = {255, 0, 0, 255};
    fillWithColour(framebuffer, c);


    gtk_init(NULL, NULL);
    mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(mainWindow), WIDTH, HEIGHT);
    gtk_window_set_title(GTK_WINDOW(mainWindow), "Framebuffer test");

    GtkWidget* drawingArea = gtk_drawing_area_new();

    gtk_container_add(GTK_CONTAINER(mainWindow), drawingArea);

    g_signal_connect(GTK_WINDOW(mainWindow), "destroy", (GCallback)onWindowDestroy, NULL);
    g_signal_connect(GTK_DRAWING_AREA(drawingArea), "draw", (GCallback)onDraw, NULL);

    g_timeout_add(500, onTimerTick, NULL);

    gtk_widget_show_all(GTK_WINDOW(mainWindow));
    pixbuf = gdk_pixbuf_new_from_data(framebuffer, GDK_COLORSPACE_RGB, true, 8, WIDTH, HEIGHT, WIDTH*4, NULL, NULL);
    gtk_main();
}
#包括
#包括
#包括
#包括
常数整数宽度=1080;
const int HEIGHT=720;
GtkWidget*主窗口;
int currentCol=0;
uint32_t*帧缓冲区=NULL;
GdkPixbuf*pixbuf=NULL;
typedef结构颜色{
uint8_t红色;
uint8_t绿色;
uint8_t蓝;
uint8_tα;
}RGB颜色;
void onWindowDestroy(GtkWidget*对象,gpointer用户\ U数据){
gtk_main_quit();
}
gboolean onTimerTick(gpointer用户\ U数据){
rgbColor c={0,0,0,255};
如果(currentCol==0){
c、 红色=255;
}
如果(currentCol==1){
c、 绿色=255;
}
如果(currentCol==2){
c、 蓝色=255;
currentCol=-1;
}
currentCol++;
填充颜色(帧缓冲区,c);
RGBColorC1={0,0,255,255};
fillEveryInterval(帧缓冲区,c1,20);
gtk_小部件_队列_绘制(主窗口);
返回1;
}
gboolean onDraw(GtkWidget*小部件、cairo\u t*cr、gpointer用户数据){
gdk_cairo_set_source_pixbuf(cr,pixbuf,0,0);
开罗漆(cr);
返回0;
}
用颜色填充空隙(uint32_t*fb,RGB颜色c){
对于(int y=0;yg=c.green您只是将像素存储在错误的位置。在
encodePixel
中,更改此行:

*(fb + (sizeof(uint32_t)*y+x)) = b | g | r | a;`
对此

fb[WIDTH*y+x] = b | g | r | a;

另一方面,您应该对编译器中的许多警告进行处理。

也许这会有所帮助:。它在python中,但做了类似的工作。查看
LoadCover
类。您可能希望删除
stdlib.h
并替换为
gmodule.h
,然后使用
framebuffer=g_slice\u alloc(sizeof(uint32_t)*宽度*高度);
进行分配,然后调用
g_slice_free(uint32_t*,(void*)帧缓冲区);
完成后。@DavidC.Rankin在这种情况下,调用
malloc
free
,因为这就是
g_slice_alloc
可能要做的。或者至少是g_malloc(
;)
谢谢,我不知道我怎么看不到这个警告,但它现在工作得很好。警告很容易修复,只是因为源代码中的函数顺序不同。在
gdk_pixbuf_new_from_data
中将帧缓冲区转换为
uint8_t*
摆脱了另一个警告,仅供任何可能的人参考我没有类似的问题。