Получить ColorData из OpenGL использовать glReadPixels - PullRequest
1 голос
/ 03 апреля 2020

Я пытаюсь использовать алгоритм заполнения границ в pyopengl.

Но когда я хочу получить цвет треугольника, он не работает хорошо.

Он просто получает цвет фона, а не цвет треугольника

Вы можете увидеть это в myDisplay () fun c. Я рисую треугольник синим цветом

    glBegin(GL_LINE_LOOP)
    glVertex2i(100, 100)
    glVertex2i(150, 100)
    glVertex2i(150, 150)

Но я не могу получить цвет это.

В то же время, я рисую линию для тестирования, но я также не могу ее цвет.

    for i in range(120, 130):
        setPixel(i, 110)
        print(i, 110, getColor(i, 110))
        print(i, 110, getColor(i, 111))
        print(i, 110, getColor(i, 109))

вот забавный c getcolor

def getColor(x, y):
    color = (GLuint * 1)(0)
    #读取点(x,y)的颜色color
    glReadPixels(122, 101, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, color)
    color=int(color[0])
    r = color & 255
    g = (color >> 8) & 255
    b = (color >> 16) & 255
    color = (r, g, b)
    return color

вот код

# -*- coding:utf-8 -*-
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


#判断c1,c2的颜色是否相同
def rgbColorEqual(c1, c2):
    # if (abs(c1[0]-c2[0]) < 0.001 and abs(c1[1], c2[1]) < 0.001 and abs(c1[2]-c2[2]) < 0.001):
    #     return 1
    # else:
    #     return 0
    return 1
#绘制像素点(x,y)
def setPixel(x, y):
    glBegin(GL_POINTS)
    glVertex2i(x, y)
    glEnd()
    glFlush()
    return
#获得点(x,y)的颜色
def getColor(x, y):
    color = (GLuint * 1)(0)
    #读取点(x,y)的颜色color
    glReadPixels(122, 101, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, color)
    color=int(color[0])
    r = color & 255
    g = (color >> 8) & 255
    b = (color >> 16) & 255
    color = (r, g, b)
    return color
#4-连通边界填充算法
def boundaryFill4(x, y, fillColor, borderColor):
    interiorColor=getColor(x,y)
    print(x,y,interiorColor)
    # if(not rgbColorEqual(interiorColor, borderColor) and not rgbColorEqual(interiorColor, fillColor)):
    #     setPixel(x, y)
    # boundaryFill4(x+1,y,fillColor,borderColor)
    # boundaryFill4(x-1,y,fillColor,borderColor)
    # boundaryFill4(x,y+1,fillColor,borderColor)
    # boundaryFill4(x,y-1,fillColor,borderColor)

#显示函数
def myDisplay():
    glClear(GL_COLOR_BUFFER_BIT)
    #设置填充色为a红色
    #设置边界色为b蓝色
    a = (1, 0, 0)
    b = (0, 0, 1)
    glColor3fv(b)
    #绘制三角形的边
    glBegin(GL_LINE_LOOP)
    glVertex2i(100, 100)
    glVertex2i(150, 100)
    glVertex2i(150, 150)
    glEnd()
    glFlush()
    #取图形中的一点,进行填充
    glColor3fv(a)
    for i in range(120, 130):
        setPixel(i, 110)
        print(i, 110, getColor(i, 110))
        print(i, 110, getColor(i, 111))
        print(i, 110, getColor(i, 109))
    for i in range(100,150):
        print(i,100,getColor(i,100))
    boundaryFill4(120, 106, a, b)


if __name__ == "__main__":
    glutInit()
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE)
    glutInitWindowPosition(100, 100)
    glutInitWindowSize(500, 500)
    glutCreateWindow('midpointcircle')
    glClearColor(0.5, 0.5, 0.5, 0)
    glMatrixMode(GL_PROJECTION)
    gluOrtho2D(0.0, 500.0, 0.0, 500.0)
    glutDisplayFunc(myDisplay)
    glutMainLoop()

1 Ответ

0 голосов
/ 03 апреля 2020

Убедитесь, что точечные и линейные примитивы нарисованы в центре пикселей. Поскольку вершины преобразуются матрицей проекции (и матрицей вида модели), они могут иметь неточности, если вы указываете вершины целочисленными координатами:

glBegin(GL_LINE_LOOP)
glVertex2f(100+0.5, 100+0.5)
glVertex2f(150+0.5, 100+0.5)
glVertex2f(150+0.5, 150+0.5)
glEnd()

Конечно, вы должны использовать x и * 1005. * координата в getColor;

glReadPixels(122, 101, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, color)

glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, color)

Кортежи сопоставимы, поэтому реализация rgbColorEqual проста:

def rgbColorEqual(c1, c2):
    return c1[0] == c2[0]

Вам необходимо setPixel и продолжить рекурсивный алгоритм, если interiorColor не равно borderColor и не равно fillColor:

def boundaryFill4(x, y, fillColor, borderColor):
    interiorColor=getColor(x,y)
    if not rgbColorEqual(interiorColor, borderColor) and not rgbColorEqual(interiorColor, fillColor):
        setPixel(x, y)
        boundaryFill4(x+1,y,fillColor,borderColor)
        boundaryFill4(x-1,y,fillColor,borderColor)
        boundaryFill4(x,y+1,fillColor,borderColor)
        boundaryFill4(x,y-1,fillColor,borderColor)

Цветовые каналы, возвращаемые getColor находятся в диапазоне [0, 255]. Я рекомендую устанавливать атрибут цвета по значениям в том же диапазоне (glColor3ubv):

def myDisplay():
    glClear(GL_COLOR_BUFFER_BIT)
    #设置填充色为a红色
    #设置边界色为b蓝色
    a = (255, 0, 0)
    b = (0, 0, 255)
    glColor3ubv(b)
    #绘制三角形的边
    glBegin(GL_LINE_LOOP)
    glVertex2f(100+0.5, 100+0.5)
    glVertex2f(150+0.5, 100+0.5)
    glVertex2f(150+0.5, 150+0.5)
    glEnd()
    glFlush()
    #取图形中的一点,进行填充
    glColor3ubv(a)
    boundaryFill4(120, 106, a, b)
    glFlush()

См. Пример:

# -*- coding:utf-8 -*-
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

#判断c1,c2的颜色是否相同
def rgbColorEqual(c1, c2):
    return c1[0] == c2[0]
#绘制像素点(x,y)
def setPixel(x, y):
    glBegin(GL_POINTS)
    glVertex2f(x+0.5, y+0.5)
    glEnd()
    glFlush()
    return
#获得点(x,y)的颜色
def getColor(x, y):
    color = (GLuint * 1)(0)
    #读取点(x,y)的颜色color
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, color)
    color=int(color[0])
    r = color & 255
    g = (color >> 8) & 255
    b = (color >> 16) & 255
    color = (r, g, b)
    return color
#4-连通边界填充算法
def boundaryFill4(x, y, fillColor, borderColor):
    interiorColor=getColor(x,y)
    if not rgbColorEqual(interiorColor, borderColor) and not rgbColorEqual(interiorColor, fillColor):
        setPixel(x, y)
        boundaryFill4(x+1,y,fillColor,borderColor)
        boundaryFill4(x-1,y,fillColor,borderColor)
        boundaryFill4(x,y+1,fillColor,borderColor)
        boundaryFill4(x,y-1,fillColor,borderColor)
    glFlush()

#显示函数
def myDisplay():
    glClear(GL_COLOR_BUFFER_BIT)
    #设置填充色为a红色
    #设置边界色为b蓝色
    a = (255, 0, 0)
    b = (0, 0, 255)
    glColor3ubv(b)
    #绘制三角形的边
    glBegin(GL_LINE_LOOP)
    glVertex2f(100+0.5, 100+0.5)
    glVertex2f(150+0.5, 100+0.5)
    glVertex2f(150+0.5, 150+0.5)
    glEnd()
    glFlush()
    #取图形中的一点,进行填充
    glColor3ubv(a)
    boundaryFill4(120, 106, a, b)
    glFlush()


if __name__ == "__main__":
    glutInit()
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE)
    glutInitWindowPosition(100, 100)
    glutInitWindowSize(500, 500)
    glutCreateWindow('midpointcircle')
    glClearColor(0.5, 0.5, 0.5, 0)
    glMatrixMode(GL_PROJECTION)
    gluOrtho2D(0.0, 500.0, 0.0, 500.0)
    glutDisplayFunc(myDisplay)
    glutMainLoop()
...