void CGLWidget::initializeGL() { qDebug() << "init gl..."; this->initializeOpenGLFunctions(); this->glClearColor(0, 0, 0, 1); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/glsl/basic.vert"); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/glsl/basic.frag"); m_program->link(); m_program->bind(); m_mvpLoc = m_program->uniformLocation("mvp"); m_vbo.create(); m_vbo.bind(); m_vbo.setUsagePattern(QOpenGLBuffer::UsagePattern::StaticDraw); m_uvBuff.create(); m_uvBuff.bind(); setupVertexAttribs(); loadGLTexture(); }
void CGLWidget::initializeGL() { qDebug() << "init gl..."; this->initializeOpenGLFunctions(); this->glClearColor(0, 0, 0, 1); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/glsl/basic.vert"); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/glsl/basic.frag"); m_program->link(); m_program->bind(); m_mvpLoc = m_program->uniformLocation("mvp"); m_modelMatLoc = m_program->uniformLocation("m"); m_viewMatLoc = m_program->uniformLocation("v"); m_lightPosLoc = m_program->uniformLocation("lightPosition_worldspace"); m_vbo.create(); m_vbo.bind(); m_uvBuff.create(); m_uvBuff.bind(); m_normalBuff.create(); m_normalBuff.bind(); m_indexBuff.create(); m_indexBuff.bind(); setupVertexAttribs(); loadGLTexture(); }
//我只在 InitGL 中增加很少的几行代码。但为了方便您查看增加了哪几行,我这段代码全部重贴一遍。 //loadGLTexture()这行代码调用载入位图并生成纹理。纹理创建好了,我们启用2D纹理映射。 //如果您忘记启用的话,您的对象看起来永远都是纯白色,这一定不是什么好事。 void MyGLWidget::initializeGL() { loadGLTexture(); glEnable(GL_TEXTURE_2D);// 启用纹理映射 //下一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。 //我将在另一个教程中更详细的解释阴影平滑。 glShadeModel(GL_SMOOTH); // 启用阴影平滑 //下一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。 //色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。 //glClearColor 后的第一个参数是Red Intensity(红色分量),第二个是绿色,第三个是蓝色。 //最大值也是1.0f,代表特定颜色分量的最亮情况。最后一个参数是Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。 //现在让它为0.0f。我会用另一个教程来解释这个参数。 //通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校里学过这些。 //因此,当您使用glClearColor(0.0f,0.0f,1.0f,0.0f),您将用亮蓝色来清除屏幕。 //如果您用 glClearColor(0.5f,0.0f,0.0f,0.0f)的话,您将使用中红色来清除屏幕。不是最亮(1.0f),也不是最暗 (0.0f)。 //要得到白色背景,您应该将所有的颜色设成最亮(1.0f)。要黑色背景的话,您该将所有的颜色设为最暗(0.0f)。 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景 //接下来的三行必须做的是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。 //深度缓存不断的对物体进入屏幕内部有多深进行跟踪。 //我们本节的程序其实没有真正使用深度缓存,但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。 //它的排序决定那个物体先画。这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。 glClearDepth(1.0f); // 设置深度缓存 glEnable(GL_DEPTH_TEST); // 启用深度测试 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 //接着告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正 }
void MyGLWidget::initializeGL() { loadGLTexture(); buildFont(); // Build The Font glClearColor (0.0f, 0.0f, 0.0f, 0.5f); // Black Background glClearDepth(1.0); // 设置深度缓存 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 glBlendFunc(GL_SRC_ALPHA,GL_ONE); // 设置混合因子 glShadeModel (GL_SMOOTH); // Select Smooth Shading glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate }
//好了我们现在开始搞InitGL()函数。我们打算增加3行代码用来初始化我们的二次曲面。 //这3行代码将在你使1号光源有效后增加,但是要在返回之前。 //第一行代码将初始化二次曲面并且创建一个指向改二次曲面的指针,如果改二次曲面不能被创建的话,那么该指针就是NULL。 //第二行代码将在二次曲面的表面创建平滑的法向量,这样当灯光照上去的时候将会好看些。 //另外一些可能的取值是:GLU_NONE和GLU_FLAT。最后我们使在二次曲面表面的纹理映射有效。 void MyGLWidget::initializeGL() { loadGLTexture(); glEnable(GL_TEXTURE_2D);// 启用纹理映射 //下一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。 //我将在另一个教程中更详细的解释阴影平滑。 glShadeModel(GL_SMOOTH); // 启用阴影平滑 //下一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。 //色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。 //glClearColor 后的第一个参数是Red Intensity(红色分量),第二个是绿色,第三个是蓝色。 //最大值也是1.0f,代表特定颜色分量的最亮情况。最后一个参数是Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。 //现在让它为0.0f。我会用另一个教程来解释这个参数。 //通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校里学过这些。 //因此,当您使用glClearColor(0.0f,0.0f,1.0f,0.0f),您将用亮蓝色来清除屏幕。 //如果您用 glClearColor(0.5f,0.0f,0.0f,0.0f)的话,您将使用中红色来清除屏幕。不是最亮(1.0f),也不是最暗 (0.0f)。 //要得到白色背景,您应该将所有的颜色设成最亮(1.0f)。要黑色背景的话,您该将所有的颜色设为最暗(0.0f)。 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景 //接下来的三行必须做的是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。 //深度缓存不断的对物体进入屏幕内部有多深进行跟踪。 //我们本节的程序其实没有真正使用深度缓存,但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。 //它的排序决定那个物体先画。这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。 glClearDepth(1.0f); // 设置深度缓存 glEnable(GL_DEPTH_TEST); // 启用深度测试 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 //接着告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正 //现在开始设置光源。下面下面一行设置环境光的发光量,光源light1开始发光。 //这一课的开始处我们我们将环境光的发光量存放在LightAmbient数组中。 //现在我们就使用此数组(半亮度环境光)。在int InitGL(GLvoid)函数中添加下面的代码。 glLightfv(GL_LIGHT1, GL_AMBIENT, m_light_ambient); // 设置环境光 //接下来我们设置漫射光的发光量。它存放在LightDiffuse数组中(全亮度白光)。 glLightfv(GL_LIGHT1, GL_DIFFUSE, m_light_diffuse); // 设置漫射光 //然后设置光源的位置。位置存放在 LightPosition 数组中(正好位于木箱前面的中心,X-0.0f,Y-0.0f,Z方向移向观察者2个单位<位于屏幕外面>)。 glLightfv(GL_LIGHT1, GL_POSITION, m_light_position); // 设置光源位置 //最后,我们启用一号光源。我们还没有启用GL_LIGHTING,所以您看不见任何光线。 //记住:只对光源进行设置、定位、甚至启用,光源都不会工作。除非我们启用GL_LIGHTING。 glEnable(GL_LIGHT1); // 启用一号光源 if(!m_light) { glDisable(GL_LIGHTING); // 禁用光源 } else { glEnable(GL_LIGHTING); // 启用光源 } m_quadratic = gluNewQuadric(); // 创建二次几何体 gluQuadricNormals(m_quadratic, GLU_SMOOTH); // 使用平滑法线 gluQuadricTexture(m_quadratic, GL_TRUE); // 使用纹理 }
void TextureMappingWindow::initialize() { initGeometry(); loadShader(); loadGLTexture(); glEnable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearDepthf(1.0); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glDisable(GL_BLEND); glBlendColor(1.0f,1.0f,1.0f,0.5f); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE); }
void Visualizer::initializeGL() { initializeOpenGLFunctions(); glClearColor(0, 0, 0, 1); initShaders(); loadGLTexture(); // Enable depth buffer glEnable(GL_DEPTH_TEST); // Enable back face culling glEnable(GL_CULL_FACE); }
void DGStarGroup::start(){ //载入纹理 if (!loadGLTexture("Assets/Data/Star.bmp", &starTextures[0])) { throw new DGException("star group texture load faild!"); } //初始化星星 int loop; for (loop=0; loop<starNum; loop++) { stars[loop].angle = (loop * 1.0f/starNum) * 360.0f * 3; stars[loop].dist = (loop * 1.0f/starNum) * 5.0f; stars[loop].r = rand() % 256 * 1.0f / 256; stars[loop].g = rand() % 256 * 1.0f / 256; stars[loop].b = rand() % 256 * 1.0f / 256; } starZoom = 15.0f; starTilt = 30.0f; starSpin = 0.0f; }
void DGBanner::start(){ wiggle_count = 0; //载入纹理 if (!loadGLTexture("Assets/Textures/Tim.bmp", &texture[0])) { throw new DGException("yramid texture load faild!"); } glPolygonMode(GL_BACK, GL_FILL); // 后表面完全填充 glPolygonMode(GL_FRONT, GL_LINE); // 前表面使用线条绘制 //初始化网格上的点 for (int x=0; x<45; x++) { for (int y=0; y<45; y++) { this->points[x][y].x = x/5.0f - 4.5f; this->points[x][y].y = y/5.0f - 4.5f; this->points[x][y].z = sin((((x/5.0f)*40.0f)/360.0f)* DGMathf::PI *2.0f); } } this->transform->position = DGVector3(0, 2.0f, 4.0f); this->transform->rotation = DGQuaternion(90.0f, 0, 0, 0); }
void Game::loadAnimations() { DIR *dir; struct dirent *ent; std::string aniPath = "./resources/animations/"; if ((dir = opendir(aniPath.c_str()))) { while ((ent = readdir(dir)) != NULL) { std::string dirName = ent->d_name; if (StringUtils::endswith(dirName, ".ani")) { std::string aniName = dirName.substr(0, dirName.length()-4); std::string imageFile(aniPath); imageFile.append(dirName); std::string dataFile(imageFile); imageFile.append("/spritesheet.png"); dataFile.append("/CelData.plist"); //std::cout << "Loading ani '" << aniName << "' with files" << std::endl << " " << imageFile << std::endl << " " << dataFile << std::endl; loadGLTexture(imageFile, aniName); m_animations[aniName] = new Animation(m_textures[aniName], dataFile); } } } else { perror("Could not open resources/animations directory!"); assert(false); } }
//现在我们已经设置了变量,接下来我们来看InitGL函数。为了获得更好的效果, //glClearColor()这行已经被修改为将屏幕清为同雾相同的颜色。使用雾效只需很少的代码。总之你将发现这很容易。 void MyGLWidget::initializeGL() { loadGLTexture(); glEnable(GL_TEXTURE_2D);// 启用纹理映射 //下一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。 //我将在另一个教程中更详细的解释阴影平滑。 glShadeModel(GL_SMOOTH); // 启用阴影平滑 //下一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。 //色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。 //glClearColor 后的第一个参数是Red Intensity(红色分量),第二个是绿色,第三个是蓝色。 //最大值也是1.0f,代表特定颜色分量的最亮情况。最后一个参数是Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。 //现在让它为0.0f。我会用另一个教程来解释这个参数。 //通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校里学过这些。 //因此,当您使用glClearColor(0.0f,0.0f,1.0f,0.0f),您将用亮蓝色来清除屏幕。 //如果您用 glClearColor(0.5f,0.0f,0.0f,0.0f)的话,您将使用中红色来清除屏幕。不是最亮(1.0f),也不是最暗 (0.0f)。 //要得到白色背景,您应该将所有的颜色设成最亮(1.0f)。要黑色背景的话,您该将所有的颜色设为最暗(0.0f)。 glClearColor(0.5f,0.5f,0.5f,1.0f); // 设置背景的颜色为雾气的颜色 glFogi(GL_FOG_MODE, m_fogMode[m_fogfilter]); // 设置雾气的模式 glFogfv(GL_FOG_COLOR, m_fogColor); // 设置雾的颜色 glFogf(GL_FOG_DENSITY, 0.35f); // 设置雾的密度 glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气 glFogf(GL_FOG_START, 1.0f); // 雾气的开始位置 glFogf(GL_FOG_END, 5.0f); // 雾气的结束位置 glEnable(GL_FOG); // 使用雾气 //让我们先看看这段代码的头三行。第一行glEnable(GL_FOG);(?这应该是最后一行)不用再解释了吧,主要是初始化雾效。 //第二行glFogi(GL_FOG_MODE, fogMode[fogfilter]);建立雾的过滤模式。之前我们声明了数组fogMode, //它保存了值GL_EXP, GL_EXP2, and GL_LINEAR。现在是使用他们的时候了。 //我来解释它们(具体见红皮书,其实这是计算雾效混合因子的三种方式): //GL_EXP - 充满整个屏幕的基本渲染的雾。它能在较老的PC上工作,因此并不是特别像雾。 //GL_EXP2 - 比GL_EXP更进一步。它也是充满整个屏幕,但它使屏幕看起来更有深度。 //GL_LINEAR - 最好的渲染模式。物体淡入淡出的效果更自然。 //第三行glFogfv(GL_FOG_COLOR, fogcolor);设置雾的颜色。之前我们已将变量fogcolor设为(0.5f,0.5f,0.5f,1.0f), //这是一个很棒的灰色。 //接下来我们看看最后的四行。glFogf(GL_FOG_DENSITY, 0.35f);这行设置雾的密度。增加数字会让雾更密,减少它则雾更稀。 //glHint (GL_FOG_HINT, GL_DONT_CARE); 设置修正。我使用了GL_DONT_CARE因为我不关心它的值。 //Eric Desrosiers Adds:关于glHint(GL_FOG_HINT, hintval);的解释 //gl_dont_care - 由OpenGL决定使用何种雾效(对每个顶点还是每个像素执行雾效计算)和一个未知的公式(?) //gl_nicest - 对每个像素执行雾效计算(效果好) //gl_fastest - 对每个顶点执行雾效计算 (更快,但效果不如上面的好) //下一行glFogf(GL_FOG_START, 1.0f);设定雾效距屏幕多近开始。你可以根据你的需要随意改变这个值。 //下一行类似,glFogf(GL_FOG_END, 5.0f);告诉OpenGL程序雾效持续到距屏幕多远。 //现在我们建立了绘制雾的代码。 //接下来的三行必须做的是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。 //深度缓存不断的对物体进入屏幕内部有多深进行跟踪。 //我们本节的程序其实没有真正使用深度缓存,但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。 //它的排序决定那个物体先画。这样您就不会将一个圆形后面的正方形画到圆形上来。深度缓存是OpenGL十分重要的部分。 glClearDepth(1.0f); // 设置深度缓存 glEnable(GL_DEPTH_TEST); // 启用深度测试 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 //接着告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正 //现在开始设置光源。下面下面一行设置环境光的发光量,光源light1开始发光。 //这一课的开始处我们我们将环境光的发光量存放在LightAmbient数组中。 //现在我们就使用此数组(半亮度环境光)。在int InitGL(GLvoid)函数中添加下面的代码。 glLightfv(GL_LIGHT1, GL_AMBIENT, m_light_ambient); // 设置环境光 //接下来我们设置漫射光的发光量。它存放在LightDiffuse数组中(全亮度白光)。 glLightfv(GL_LIGHT1, GL_DIFFUSE, m_light_diffuse); // 设置漫射光 //然后设置光源的位置。位置存放在 LightPosition 数组中(正好位于木箱前面的中心,X-0.0f,Y-0.0f,Z方向移向观察者2个单位<位于屏幕外面>)。 glLightfv(GL_LIGHT1, GL_POSITION, m_light_position); // 设置光源位置 //最后,我们启用一号光源。我们还没有启用GL_LIGHTING,所以您看不见任何光线。 //记住:只对光源进行设置、定位、甚至启用,光源都不会工作。除非我们启用GL_LIGHTING。 glEnable(GL_LIGHT1); // 启用一号光源 if(!m_light) { glDisable(GL_LIGHTING); // 禁用光源 } else { glEnable(GL_LIGHTING); // 启用光源 } }
void MyGL::drawMesh() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -600); glTranslatef(translationX, translationY, translationZ); glRotatef(rotationX, 1.0, 0.0, 0.0); glRotatef(rotationY, 0.0, 1.0, 0.0); glRotatef(rotationZ, 0.0, 0.0, 1.0); //画点 glColor3f(1.0f, 1.0f, 1.0f); //打上所有点 for (auto it = petal_mesh.halfedges_begin(); it != petal_mesh.halfedges_end(); ++it) { auto fromv = petal_mesh.from_vertex_handle(it.handle()); auto tov = petal_mesh.to_vertex_handle(it.handle()); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINES); glVertex3f((GLfloat)petal_mesh.point(fromv).data()[0], (GLfloat)petal_mesh.point(fromv).data()[1], (GLfloat)petal_mesh.point(fromv).data()[2]); glVertex3f((GLfloat)petal_mesh.point(tov).data()[0], (GLfloat)petal_mesh.point(tov).data()[1], (GLfloat)petal_mesh.point(tov).data()[2]); glEnd(); } glPointSize(1); //使得能够旋转 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.5f, 0.0f, 0.0f); glEnd(); glColor3f(1.0f, 1.0f, 1.0f); //纹理 if (!match_tex.empty())//有纹理 { //载入纹理 loadGLTexture(); //启用纹理 glEnable(GL_TEXTURE_2D); //纹理映射 for (int i = 0; i < face.size(); i++) { int a, b, c; //得到对应vhandles的索引 a = face[i].x ; b = face[i].y; c = face[i].z ; /* 设置纹理坐标和物体几何坐标 */ glBegin(GL_TRIANGLES); double t[2] = { match_tex[a%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[a%match_tex.size()].x()) / (gheight*1.0) }; glTexCoord2f(match_tex[a%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[a%match_tex.size()].x()) / (gheight*1.0)); glVertex3f(points[a].x, points[a].y, points[a].z); double t1[2] = { match_tex[b%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[b%match_tex.size()].x()) / (gheight*1.0) }; glTexCoord2f(match_tex[b%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[b%match_tex.size()].x()) / (gheight*1.0)); glVertex3f(points[b].x, points[b].y, points[b].z); double t2[2] = { match_tex[c%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[c%match_tex.size()].x()) / (gheight*1.0) }; glTexCoord2f(match_tex[c%match_tex.size()].y() / (gwidth*1.0), (gheight - match_tex[c%match_tex.size()].x()) / (gheight*1.0)); glVertex3f(points[c].x, points[c].y, points[c].z); glEnd(); } } return; }
bool initTextures() { int LoadTexture = loadGLTexture("res\\Texture\\BlockTexture.AImg"); return true; }