D7D8设置地图交互

上一次提到绘制了轮廓,接下来我们需要让其在特定触发之后相应。我们可以设置回调函数监测准心的位置。

本来想使用鼠标触发,但是在前几天的调试中,发现从窗口检测鼠标坐标并不能很好的与窗口内物体匹配。所以我先试试。

标志物交互

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);	

先释放一下鼠标

。。。

思来想去,还是用准心好了:)

当然这一步依旧,接着设置回调函数监视

glfwSetCrosshairCallback(window, Crosshair_callback);

去renderer.h中声明一下

void Crosshair_callback(GLFWwindow * window);

再renderer.cpp中定义(使用摄像机位置去判断准心是否在标志点之上 ,届时我们会禁用鼠标控制视角,限制在空间中自由移动的能力)

(不放在回填函数里也行哈,随着渲染循环,也可以实现相同的效果,而且更简便)

----------------------------------------------------------------------------------------------------------------------------

稍微有点乱,整理好了之后重来一遍

标志物交互2.0

声明一个数组,待会用它存放几个对应的摄像机位置

std::vector<glm::vec3> outlinePos;

 添加一个绘制轮廓的条件

if (
    (camera.m_Position.x <= (outlinePos[i].x + 0.2f) && camera.m_Position.x >=         (outlinePos[i].x - 0.2f)) 

    &&

    (camera.m_Position.y <= (outlinePos[i].y + 0.2f) && camera.m_Position.y >= (outlinePos[i].y - 0.2f))
) 
//格式调整了一下方便阅读,大概就是在一个正方形区域时满足条件

 接下来print摄像机位置到控制台,记录下来

接下来使用该函数在渲染循环中,更改绘制轮廓的语句

//绘制outlining
GLCALL(glStencilMask(0x00));																				//禁止模板写入
GLCALL(glStencilFunc(GL_NOTEQUAL, 1, 0xff));																//模板值不等于缓冲区中模板值时更新 通过测试
glDisable(GL_DEPTH_TEST);																					//选中的物体可以透过遮挡,不使用深度测试
outlineShader.Bind();
outlineShader.SetUniformMatrix4fv("u_Projection", projection.GetMatrixData());
outlineShader.SetUniformMatrix4fv("u_View", view.GetMatrixData());
for(size_t i = 0; i < outlinePos.size(); i++){
    if ((camera.m_Position.x <= (outlinePos[i].x + 0.2f) && camera.m_Position.x >= (outlinePos[i].x - 0.2f)) && (camera.m_Position.y <= (outlinePos[i].y + 0.2f) && camera.m_Position.y >= (outlinePos[i].y - 0.2f)))
    {
        Matrix stencilModel("mat4");
        stencilModel.Rotate(90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
        stencilModel.Translate(labels[i]);
        stencilModel.Scale(glm::vec3(1.5f, 1.5f, 1.5f));
        outlineShader.SetUniformMatrix4fv("u_Model", stencilModel.GetMatrixData());
        renderer.DrawElements(cuboidVa, cuboidIb, outlineShader);
    }
}
glEnable(GL_DEPTH_TEST);																					//恢复深度测试
GLCALL(glStencilMask(0xFF));

现在我看谁,谁就得给我高亮

标志物信息展示

首先考虑在此窗口中展示信息,如此一来,新建一个视口显然合适一点。

首先我们声明一个布尔变量mes(这个mes变量需要在渲染循环中,通过每一次渲染重复刷新),然后在上一次的轮廓渲染中添加一个储存状态的变量

bool mes = false;
//...
for(){
    if () 
    {
        renderer.DrawElements(cuboidVa, cuboidIb, outlineShader);
        mes = true;        //添加
     }
}

随后通过

if (mes) {
                GLCALL(glDisable(GL_DEPTH_TEST));
                GLCALL(glViewport(0, 0, SCR_WIDTH / 4, SCR_HEIGHT / 4));
                quadShader.Bind();
                texMes.Bind(0);
                renderer.DrawArrays(quadVa, 6, quadShader);
            }

来实现绘制轮廓的同时绘制这个小窗口

没看的时候

看的时候

方便起见呢,我将每一个标志点的信息通过截图的方式储存,届时绘制纹理即可。

更改

            //绘制outlining
            bool mes = false;
            std::string message;
            GLCALL(glStencilMask(0x00));																				//禁止模板写入
            GLCALL(glStencilFunc(GL_NOTEQUAL, 1, 0xff));																//模板值不等于缓冲区中模板值时更新 通过测试
            glDisable(GL_DEPTH_TEST);																					//选中的物体可以透过遮挡,不使用深度测试
            outlineShader.Bind();
            outlineShader.SetUniformMatrix4fv("u_Projection", projection.GetMatrixData());
            outlineShader.SetUniformMatrix4fv("u_View", view.GetMatrixData());
            for(size_t i = 1; i < outlinePos.size() + 1; i++){
                if ((camera.m_Position.x <= (outlinePos[i - 1].x + 0.2f) && camera.m_Position.x >= (outlinePos[i - 1].x - 0.2f)) && (camera.m_Position.y <= (outlinePos[i - 1].y + 0.2f) && camera.m_Position.y >= (outlinePos[i - 1].y - 0.2f))) 
                {
                    Matrix stencilModel("mat4");
                    stencilModel.Rotate(90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
                    stencilModel.Translate(labels[i - 1]);
                    stencilModel.Scale(glm::vec3(1.5f, 1.5f, 1.5f));
                    outlineShader.SetUniformMatrix4fv("u_Model", stencilModel.GetMatrixData());
                    renderer.DrawElements(cuboidVa, cuboidIb, outlineShader);
                    mes = i;
                    message = "tex" + 'i';
                }
            }
            glEnable(GL_DEPTH_TEST);																					//恢复深度测试
            GLCALL(glStencilMask(0xFF));
            //-----------------------------------------------------------------------------------------
            if (mes) {
                GLCALL(glDisable(GL_DEPTH_TEST));
                GLCALL(glViewport(SCR_WIDTH / 3, SCR_WIDTH / 2.5, SCR_WIDTH / 2.5, SCR_HEIGHT / 2.5));
                quadShader.Bind();
                tex1.Bind(0);
                renderer.DrawArrays(quadVa, 6, quadShader);
            }

 1.为了方便在if(mes){ }中控制不同的纹理,对应不同的情况。2.调整窗口方位。3.添加了一个变量message存储每一个绘制的物体的编号(从1到12,而不是0到11)

1.for(size_t i = 1; i < outlinePos.size() + 1; i++){
                2.if ((camera.m_Position.x <= (outlinePos[i - 1].x + 0.2f) && camera.m_Position.x >= (outlinePos[i - 1].x - 0.2f)) && (camera.m_Position.y <= (outlinePos[i - 1].y + 0.2f) && camera.m_Position.y >= (outlinePos[i - 1].y - 0.2f)))
3.stencilModel.Translate(labels[i - 1]);

我在这三句代码中特定更改了i值,和条件中涉及i的地方。现在虽然只在if(mes){}中绑定了一个tex1,但是效果不错了

现在想的是通过message来实现tex1到tex12的控制,然后将字符转换为texture类型,通过“tex1.Bind(0);”实现对应纹理分配。

现在就是实现不同的纹理绘制了

最后一步

明天弄吧,睡了。明天弄一下不同的纹理控制,然后设置决赛信息交互。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值