ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

opengl 高级技巧

2021-09-30 22:00:03  阅读:154  来源: 互联网

标签:1.0 glm opengl 矩阵 高级 vec3 const mat4Model 技巧


1 glOrtho 投影变换,使得和uv坐标一致

在二维平面顶点坐标和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 << "显卡供应商   : " << vendor << endl;
	cout << "显卡型号     : " << renderer << endl;
	cout << "OpenGL版本   : " << version << endl;
	cout << "GLSL版本     : " << glslVersion << endl;

标签:1.0,glm,opengl,矩阵,高级,vec3,const,mat4Model,技巧
来源: https://blog.csdn.net/qianbo042311/article/details/120572600

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有