C++ 使用OpenGL/Cocos2dx在非递归泛洪填充中未渲染任何内容

C++ 使用OpenGL/Cocos2dx在非递归泛洪填充中未渲染任何内容,c++,opengl,cocos2d-x,C++,Opengl,Cocos2d X,我正在尝试给Cocos2dx场景中的一个区域上色。场景只是一个精灵(测试用黑白背景图片)。我有一个单击事件的侦听器 Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if

我正在尝试给Cocos2dx场景中的一个区域上色。场景只是一个精灵(测试用黑白背景图片)。我有一个单击事件的侦听器

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    // creating the sprite
    Sprite* background = Sprite::create("image.jpg");
    background->setPosition(origin);
    background->setAnchorPoint(origin);
    addChild(background,-2);

    // creating listener
    auto dispatcher = Director::getInstance()->getEventDispatcher();
    auto listener = EventListenerTouchOneByOne::create();

    listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);

    dispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}


// event when clicked
bool HelloWorld::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event)
{
    cocos2d::Vec2 touchPosition = touch->getLocation();
    Color whiteColor = { 1.0f, 1.0f, 1.0f };
    Color newColorTest = { 1.0f, 0.0f, 0.0f };

    floodFill(touchPosition.x, touchPosition.y, whiteColor, newColorTest);

    return true;
}
我正试图用OpenGL给一个连续的白色区域上色。这就是我的努力

Color HelloWorld::getPixelColor(GLint x, GLint y) 
{
    Color color;
    float pixels[3];
    glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, pixels);
    color.r = pixels[0];
    color.g = pixels[1];
    color.b = pixels[2];

    return color;
}
// drawing pixel by pixel.
void HelloWorld::setPixelColor(GLint x, GLint y, Color color) 
{

    cocos2d::log("bar");
    glColor3f(color.r, color.g, color.b);
    glBegin(GL_POINTS);
        glVertex2i(x, y);
    glEnd();

    glFlush();
}

void HelloWorld::floodFill(GLint x, GLint y, Color oldColor, Color newColor)
{
    Color color;
    std::stack<GLPoint> stack;
    GLPoint clickedPoint = { x, y };
    int w = Director::getInstance()->getVisibleSize().width;
    int h = Director::getInstance()->getVisibleSize().height;

    cocos2d::log("test");

    if (x < 0 || y < 0 || x > w || y > h)
    {
        cocos2d::log("out of bonds");
        return;
    }


    stack.push(clickedPoint);

    // while there is pixels to process.
    while (!stack.empty())
    {
        GLPoint point = stack.top();
        stack.pop();

        // if out of bonds
        if (point.x < 0 || point.y < 0 || point.x > w || point.y > h)
            continue;

        color = getPixelColor(point.x, point.y);
        // if the pixel is of the colors looked for.
        if (color.r == oldColor.r && color.g == oldColor.g && color.b == oldColor.b)
        {

            cocos2d::log("foo");
            // colour it
            setPixelColor(point.x, point.y, newColor);

            // add its neighbour to the stack
            stack.push({ x + 1, y });
            stack.push({ x - 1, y });
            stack.push({ x , y + 1 });
            stack.push({ x, y - 1});
        }
    }
}
在执行过程中,泛光填充迭代似乎正确发生,但并没有像素改变颜色,而setPixelColor方法被大量调用。我不知道为什么。这是我第一次使用OpenGL,也是第一次使用Cocos

编辑:我添加了一些用于创建窗口的OpenGL代码:

void AppDelegate::initGLContextAttrs()
{
    //set OpenGL context attributions,now can only set six attributions:
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    GLView::setGLContextAttrs(glContextAttrs);
}

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::createWithRect("Coloriage", Rect(0, 0, 357, 500));
        director->setOpenGLView(glview);
    }

    director->getOpenGLView()->setDesignResolutionSize(357, 500, ResolutionPolicy::SHOW_ALL);

    // rest of method is code needed for Cocos (setting animation interval, //turning off the fps data display and creating the first cocos2d::Scene)
    return true;
}

您正在使用哪个版本的OpenGL(或者cocos2d-x正在使用哪个版本)?您似乎没有设置任何其他OpenGL状态。当前的矩阵模式是什么?你设置了正交投影吗?我不知道cocos2d-x是否为您做了这些事情,但您至少要确保在渲染矩阵堆栈时是正确的。@Sam我在Cocos和OpenGL中都是乞丐,所以我不确定是否理解您的问题,但我会尝试回答。根据github,Cocos2dx使用OpenGL 2.1作为桌面,OpenGL ES 2.0作为移动设备。有一些OpenGL函数用于创建窗口,我将编辑有关显示窗口的消息。当前矩阵模式:不知道,我在哪里可以看到?正交投影:我认为没有,因为我不知道它是什么(但正如你所说,也许cocos2dx为我做了这个)@Sam:我猜现在我点击的Cocos坐标和OpenGL使用的坐标系统之间有点不对劲。你应该在cocos2d-x中找到一些使用OpenGL的示例或教程,因为如果你没有正确设置OpenGL状态,黑屏是很常见的,还有很多事情要做,可能会出错。如果您能创建一个演示问题的最小、完整的程序,这将使帮助变得更容易,例如,可能只画一个三角形。@Sam Ok。在过去的一个小时里,我阅读了一些OpenGL文档,我对它的工作原理有了更好的理解(投影矩阵等)。我将尝试使用“glDrawPixels”,如果没有任何结果,我将使用最小程序绘制三角形。
void AppDelegate::initGLContextAttrs()
{
    //set OpenGL context attributions,now can only set six attributions:
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

    GLView::setGLContextAttrs(glContextAttrs);
}

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::createWithRect("Coloriage", Rect(0, 0, 357, 500));
        director->setOpenGLView(glview);
    }

    director->getOpenGLView()->setDesignResolutionSize(357, 500, ResolutionPolicy::SHOW_ALL);

    // rest of method is code needed for Cocos (setting animation interval, //turning off the fps data display and creating the first cocos2d::Scene)
    return true;
}