在二维平面顶点坐标和uv 纹理坐标如何做到一致而不用计算? 像一下这么使用
glOrtho(0,1,1,0,-1,100);
接下去的坐标就可以由原来的负数变成和uv 一致 //传递顶点和纹理坐标 //顶点 // static const GLfloat ver[] = { // -1.0f,-1.0f, // 1.0f,-1.0f, // -1.0f, 1.0f, // 1.0f,1.0f // };
我们知道opengl 标准坐标是 左右 -1 到 1, 上下是 1 到 -1 ,而整个屏幕的中间才是 0,0,0,也就是原点, 但是经过 glOrtho(0,1,1,0,-1,100); 变换后,就可以变成 左右 0 到1 上下也是0 到 1 ,是不是可以和 uv 坐标一致了,是的! 上面的矩阵变成下面的 static const GLfloat ver[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; 这下,tex 和 ver 可以使用同一个矩阵了。
2 和glsl 兼容问题一旦使用glOrtho 和 glPers glFrustum 等函数时, glsl 中的顶点坐标依然是 (-1 ,1) , 那么怎么和glOrtho 等投影矩阵一致呢?我们熟知的三个矩阵投影变换模型矩阵 1 变换矩阵 2 投影矩阵 3 模型观察矩阵 要做乘法和顶点相乘,也就是:
uniform mat4 projMat;
uniform mat4 viewMat;
uniform mat4 modelMat;
三个相乘 我们来写个glsl 以下是顶点着色器
const char *vsrc = "#version 330\n"
"uniform mat4 projMat;\n"
"uniform mat4 viewMat;\n"
"uniform mat4 modelMat; \n"
"in vec3 pos;\n"
"in vec2 texin;\n"
"out vec2 texCoord;\n"
"void main()\n"
"{\n"
" gl_Position = * vec4(pos, 1.0);\n"
" texCoord = texin;\n"
"}\n";
以下是片元着色器
const char *fsrc =
"#version 330\n"
"out mediump vec4 color;\n"
"in vec2 texCoord;\n"
"uniform sampler2D tex\n;"
"void main()\n"
"{\n"
" color = texture(tex, texCoord);\n"
//" color = vec4(1.0, 0.0, 0.0, 0.0);\n"
"}\n";
计算三个矩阵要传进去才能正确,为了避免使用矩阵传入,一种方法是,在glsl 语言里面依然使用原坐标,二种方法是,使用兼容glsl
const char *vsrc = "#version 330 compatibility\n"
"in vec3 pos;\n"
"in vec2 texin;\n"
"out vec2 texCoord;\n"
"void main()\n"
"{\n"
" gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);\n"
" texCoord = texin;\n"
"}\n";
神奇的是,以前的的版本有一个全局变量叫gl_ModelViewProjectionMatrix,可以不用我们手动计算,代价是要加上compatibility 。
当然,我们可以手动获取投影矩阵的值,像以下这样:
float mat[16];
glGetFloatv(GL_PROJECTION_MATRIX, mat);
3、使用glm 计算矩阵
当然,除了使用兼容方式,可以使用glm 来计算投影变换模型矩阵
m_mat4View = glm::lookAt(glm::vec3(0, 0, -1), glm::vec3(0, 0, 0), glm::vec3(0, -1, 0));
m_mat4Projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f);
m_mat4Model = glm::mat4(1.0f);
m_mat4Model = glm::translate(m_mat4Model, glm::vec3(m_fXTranslate, m_fYTranslate, m_fZTranslate));
m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fXRotateDegree), glm::vec3(1.0f, 0, 0));
m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fYRotateDegree), glm::vec3(0, 1.0f, 0));
m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fZRotateDegree), glm::vec3(0, 0, 1.0f));
m_mat4Model = glm::scale(m_mat4Model, glm::vec3(m_fXScale, m_fYScale, m_fZScale));
m_mat4ProjectionModelView = m_mat4Projection * m_mat4View * m_mat4Model;
glUniformMatrix4fv(m_iProjectionModelViewIDUniform, 1, GL_FALSE, &m_mat4ProjectionModelView[0][0]);
这样,把计算的m_mat4ProjectionModelView 传到glsl 中也是可以的
#version 330 core
uniform mat4 ProjectionModelView;
in vec4 vertexCoord;
in vec2 textureCoord;
out vec2 outTextureCoord;
void main(void){
gl_Position = ProjectionModelView * vertexCoord;
outTextureCoord = textureCoord;
}
#version 330 core
in vec2 outTextureCoord;
uniform sampler2D textureY;
void main(void)
{
vec3 bgr;
bgr = texture2D(textureY, outTextureCoord).rgb;
gl_FragColor = vec4(bgr, 1.0);
}
3、效率问题
使用RGBA 还是 YUV 还是 RGB 这个很是奇特,yuv数据很小,RGB, 数据翻了一倍,而RGBA 则更多,是不是yuv效率最高?不是,是RGBA。 显卡的4字节对齐就是这样的,不过可以使用glPixelStorei 来指定打包传输的字节对齐,GL_UNPACK_ALIGNMENT,是内存到显卡的传送,如下指定为1字节对齐 glPixelStorei(GL_UNPACK_ALIGNMENT,1); 这个函数在不同的操作系统和不同的驱动下表现不同,为了不用做那么多的测试,请使用RGBA方式。这种方式始终表现良好
4、 查看信息//查看显卡、GLSL和OpenGL的信息
const GLubyte *vendor = glGetString(GL_VENDOR);
const GLubyte *renderer = glGetString(GL_RENDERER);
const GLubyte *version = glGetString(GL_VERSION);
const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?