关于七巧板中某些需要提一嘴的技术实现
程序员文章站
2022-05-20 22:51:15
...
关于七巧板中某些需要提一嘴的技术实现
- 注:本篇只提及技术实现思路,不涉及完整源码
判断鼠标点击是否能取到某个图形
- 这个东西还是班里的算法大佬给的我思路:“你取到鼠标当前点,和三角形的三个边拼成三角形去计算面积,如果你的鼠标在三角形内,则这三个三角形面积和等于原三角形,否则这三个三角形面积和要大于原三角形。”,我当场直呼内行,大佬就是大佬。(另外一个大佬跟我讲用海伦公式可以很容易算出三角形面积)
- 所以接下来我首先实现了海伦公式封装了一个函数。
- 接着我得取到鼠标点击位置,这个在Openglio回调部分提到怎么做OpenGL入手(io回调)
- 然后具体图形具体实现判断方式,拿三角形来说就是上面的判断方法。其他图形也类似。
图形动态颜色
- 因为刚入手OpenGL,操作还很生疏,可能有更高端的操作能实现动态更改图形渲染颜色,但我不会,所以我就在c++中用了本办法+动态编译其shader进行了动态颜色的实现。
- 我先搓了一个字符串作为片元着色器的代码。然后每次颜色改变我给这个字符串重新赋值,赋值代码如下:
fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(" + Convert(color[0]) + "," + Convert(color[1]) + "," + Convert(color[2]) + "," + Convert(color[3]) + ");\n"
"}\n\0";
- 说白了就是要拼接代码,把颜色属性给拼进去。然后是如何用这个string对象去编译shader。这部分由于编译API只接受const glchar* const* 对象,所以直接.c_str()是不行的。这边我定义了一个新的char对象,为其动态分配好相当于string长度加一的内存(因为string不会把最后的’\0’算长度,所以为了把这玩意一起加上去,长度要加一)。接着把string中的内容考进去就行。用这个新的char对象编译shader就可以了,代码如下
void Graph::CreateFragmentShader()
{
fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(" + Convert(color[0]) + "," + Convert(color[1]) + "," + Convert(color[2]) + "," + Convert(color[3]) + ");\n"
"}\n\0";
char* ShaderSource = (char*)malloc((fragmentShaderSource.length() + 1) * sizeof(char));
int i = 0;
for (; i < fragmentShaderSource.length(); i++)
{
ShaderSource[i] = fragmentShaderSource[i];
}
ShaderSource[i] = '\0';
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
//把片元着色器源码绑定给刚刚实例化的对象
//第一个参数是着色器对象,第二个参数是源码有几个字符串,第三个参数是源码,第四个暂时设置为空
glShaderSource(fragmentShader, 1, &ShaderSource, NULL);
//动态编译他
glCompileShader(fragmentShader);
//定义一个整形来检测编译是否成功
GLint success;
//错误日志的存储区
GLchar infoLog[512];
//检查编译是否成功,将结果给success
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
//编译失败就打印日志
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
推荐阅读