OpenGL 几何着色器 传入点,绘制三角形
2017-03-02 16:10
399 查看
几何着色器有意思的地方在于它可以把(一个或多个)顶点转变为完全不同的基本图形(primitive),从而生成比原来多得多的顶点。
main.cpp
Shader
GLSL
vertex.vx
geo.geo
frag.fg
加入视图功能:
3D图形的表示要经过几个经典的坐标转换,首先从局部到世界坐标系,再从世界坐标系到观察坐标系。
局部坐标系—>世界坐标系—>观察坐标系
顶点着色器中:
//gl_Position = vec4(pos, 1.0f);
gl_Position = projection * view * model * vec4(pos, 1.0f);
main.cpp 中
源码下载:
http://download.csdn.net/detail/yulinxx/9769051
main.cpp
#define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include <SOIL/SOIL.h> #include "Shader.h" #pragma comment(lib, "SOIL.lib") #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glew32s.lib") #pragma comment (lib, "glfw3.lib") #pragma comment (lib, "glfw3dll.lib") #pragma comment (lib, "glew32mxs.lib") #pragma comment (lib, "assimp.lib") #define WIDTH 800 #define HEIGH 600 int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* pWnd = glfwCreateWindow(WIDTH, HEIGH, "OGL Geometry Shader", nullptr, nullptr); glfwMakeContextCurrent(pWnd); glewExperimental = GL_TRUE; glewInit(); glViewport(0, 0, WIDTH, HEIGH); GLfloat fPoint[] = { 0.0f, 0.0f, 0.0f, 0.4f, 0.3f, 0.0f, 0.5f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.6f, 0.0f, 0.0f, 1.0f, 1.0f, -0.2f, -0.5f, 0.0f, 0.0f, 0.4f, 1.0f, - 0.8f, 0.3f, 0.0f, 1.0f, 0.30f, 1.0f }; GLuint nVAO, nVBO; glGenVertexArrays(1, &nVAO); glBindVertexArray(nVAO); { glGenBuffers(1, &nVBO); glBindBuffer(GL_ARRAY_BUFFER, nVBO); { glBufferData(GL_ARRAY_BUFFER, sizeof(fPoint), fPoint, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // vertex glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6* sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); // color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6* sizeof(GLfloat), (GLvoid*)(3 * sizeof(GL_FLOAT))); } glBindBuffer(GL_ARRAY_BUFFER, 0); } glBindVertexArray(0); glEnable(GL_PROGRAM_POINT_SIZE); Shader shader("./Shader/vertex.vx", "./Shader/geo.geo", "./Shader/frag.fg"); //Shader shader("./Shader/vertex.vx", "./Shader/frag.fg"); shader.userShaderProg(); while (!glfwWindowShouldClose(pWnd)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(nVAO); { //glDrawArrays(GL_TRIANGLES, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); glDrawArrays(GL_POINTS, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); //glDrawArrays(GL_LINE_STRIP, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); } glBindVertexArray(0); glfwSwapBuffers(pWnd); } return 0; }
Shader
#pragma once #include <glew.h> class Shader { public: Shader(const GLchar* pVertexPath, const GLchar* pFragPath); Shader(const GLchar* pVertexPath, const GLchar* pGeomPath, const GLchar* pFragPath); ~Shader(); public: void userShaderProg(); GLuint getProg(); private: void initShader(const GLchar* pVertexPath, const GLchar* pFragPath); void initShader(const GLchar* pVertexPath, const GLchar* pGeomPath, const GLchar* pFragPath); private: GLuint m_nProg; };
#include <string> #include <fstream> #include <sstream> #include <iostream> #include "Shader.h" Shader::Shader(const GLchar* pVertexPath, const GLchar* pFragPath) { initShader(pVertexPath, pFragPath); } Shader::Shader(const GLchar* pVertexPath, const GLchar* pGeomPath, const GLchar* pFragPath) { initShader(pVertexPath, pGeomPath, pFragPath); } Shader::~Shader() { glDeleteProgram(m_nProg); } void Shader::userShaderProg() { glUseProgram(m_nProg); } GLuint Shader::getProg() { return m_nProg; } void Shader::initShader(const GLchar* pVertexPath, const GLchar* pFragPath) { std::string strVertexCode; std::string strFragCode; std::ifstream sVertexShaderF; std::ifstream sFragShaderF; sVertexShaderF.exceptions(std::ifstream::badbit); sFragShaderF.exceptions(std::ifstream::badbit); try { sVertexShaderF.open(pVertexPath); sFragShaderF.open(pFragPath); std::stringstream sVertexShaderStream, sGeomShaderStream, sFragShaderStream; sVertexShaderStream << sVertexShaderF.rdbuf(); sFragShaderStream << sFragShaderF.rdbuf(); sVertexShaderF.close(); sFragShaderF.close(); strVertexCode = sVertexShaderStream.str(); strFragCode = sFragShaderStream.str(); } catch (const std::exception& e) { std::cout << "ERROR ON std::exception" << e.what() << std::endl; } catch (const std::ifstream& e) { std::cout << "ERROR ON td::ifstream&" << e.rdbuf() << std::endl; } const GLchar* pChVertexCode = strVertexCode.c_str(); const GLchar* pChFragCode = strFragCode.c_str(); GLuint nVertexShader, nGeomShader, nFragShader; GLint nRes = 0; GLchar chLogInfo[512] = { '\0' }; // Create Vertex Shader Program nVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(nVertexShader, 1, &pChVertexCode, nullptr); glCompileShader(nVertexShader); glGetShaderiv(nVertexShader, GL_COMPILE_STATUS, &nRes); if (!nRes) { glGetShaderInfoLog(nVertexShader, 512, nullptr, chLogInfo); std::cout << "ERORR ON VERTES SHADER:" << chLogInfo << std::endl; } // Create Fragement Shader Program nFragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(nFragShader, 1, &pChFragCode, nullptr); glCompileShader(nFragShader); glGetShaderiv(nFragShader, GL_COMPILE_STATUS, &nRes); if (!nRes) { glGetShaderInfoLog(nFragShader, 512, nullptr, chLogInfo); std::cout << "ERROR ON FRAGMENT SHADER:" << chLogInfo << std::endl; } // Create Shader Programe m_nProg = glCreateProgram(); glAttachShader(m_nProg, nVertexShader); glAttachShader(m_nProg, nFragShader); glLinkProgram(m_nProg); glGetProgramiv(m_nProg, GL_LINK_STATUS, &nRes); if (!nRes) { glGetProgramInfoLog(m_nProg, 512, nullptr, chLogInfo); std::cout << "ERROR ON PROGRAME:" << chLogInfo << std::endl; } glDeleteShader(nVertexShader); glDeleteShader(nFragShader); } void Shader::initShader(const GLchar* pVertexPath, const GLchar* pGeomPath, const GLchar* pFragPath) { std::string strVertexCode; std::string strGeomCode; std::string strFragCode; std::ifstream sVertexShaderF; std::ifstream sGeomShaderF; std::ifstream sFragShaderF; sVertexShaderF.exceptions(std::ifstream::badbit); sGeomShaderF.exceptions(std::ifstream::badbit); sFragShaderF.exceptions(std::ifstream::badbit); try { sVertexShaderF.open(pVertexPath); sGeomShaderF.open(pGeomPath); sFragShaderF.open(pFragPath); std::stringstream sVertexShaderStream, sGeomShaderStream, sFragShaderStream; sVertexShaderStream << sVertexShaderF.rdbuf(); sGeomShaderStream << sGeomShaderF.rdbuf(); sFragShaderStream << sFragShaderF.rdbuf(); sVertexShaderF.close(); sGeomShaderF.close(); sFragShaderF.close(); strVertexCode = sVertexShaderStream.str(); strGeomCode = sGeomShaderStream.str(); strFragCode = sFragShaderStream.str(); } catch (const std::exception& e) { std::cout << "ERROR ON std::exception" << e.what() << std::endl; } catch (const std::ifstream& e) { std::cout << "ERROR ON td::ifstream&" << e.rdbuf() << std::endl; } const GLchar* pChVertexCode = strVertexCode.c_str(); const GLchar* pChGeomCode = strGeomCode.c_str(); const GLchar* pChFragCode = strFragCode.c_str(); GLuint nVertexShader, nGeomShader, nFragShader; GLint nRes = 0; GLchar chLogInfo[512] = { '\0' }; // Create Vertex Shader Program nVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(nVertexShader, 1, &pChVertexCode, nullptr); glCompileShader(nVertexShader); glGetShaderiv(nVertexShader, GL_COMPILE_STATUS, &nRes); if (!nRes) { glGetShaderInfoLog(nVertexShader, 512, nullptr, chLogInfo); std::cout << "ERORR ON VERTES SHADER:" << chLogInfo << std::endl; } // Create Geometry Shader Program nGeomShader = glCreateShader(GL_GEOMETRY_SHADER); glShaderSource(nGeomShader, 1, &pChGeomCode, nullptr); glCompileShader(nGeomShader); glGetShaderiv(nGeomShader, GL_COMPILE_STATUS, &nRes); if (!nRes) { glGetShaderInfoLog(nGeomShader, 512, nullptr, chLogInfo); std::cout << "ERORR ON GEOMETRY SHADER:" << chLogInfo << std::endl; } // Create Fragement Shader Program nFragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(nFragShader, 1, &pChFragCode, nullptr); glCompileShader(nFragShader); glGetShaderiv(nFragShader, GL_COMPILE_STATUS, &nRes); if (!nRes) { glGetShaderInfoLog(nFragShader, 512, nullptr, chLogInfo); std::cout << "ERROR ON FRAGMENT SHADER:" << chLogInfo << std::endl; } // Create Shader Programe m_nProg = glCreateProgram(); glAttachShader(m_nProg, nVertexShader); glAttachShader(m_nProg, nGeomShader); glAttachShader(m_nProg, nFragShader); glLinkProgram(m_nProg); glGetProgramiv(m_nProg, GL_LINK_STATUS, &nRes); if (!nRes) { glGetProgramInfoLog(m_nProg, 512, nullptr, chLogInfo); std::cout << "ERROR ON PROGRAME:" << chLogInfo << std::endl; } glDeleteShader(nVertexShader); glDeleteShader(nGeomShader); glDeleteShader(nFragShader); }
GLSL
vertex.vx
#version 330 core layout (location = 0) in vec3 pos; layout (location = 1) in vec3 inColor; out VS_OUT { vec3 color; } outColor; void main() { gl_PointSize = 6; gl_Position = vec4(pos, 1.0f); outColor.color = inColor; }
geo.geo
#version 330 core layout (points) in; layout (triangle_strip, max_vertices = 6) out; in VS_OUT { vec3 color; } inColor[]; out VS_OUT { vec3 color; } outColor; void main() { outColor.color = inColor[0].color; gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0); EmitVertex(); gl_Position = gl_in[0].gl_Position + vec4(0.1, 0.2, 0.0, 0.0); EmitVertex(); gl_Position = gl_in[0].gl_Position + vec4(0.3, -0.2, 0.0, 0.0); EmitVertex(); EndPrimitive(); }
frag.fg
#version 330 core in VS_OUT { vec3 color; } inColor; out vec4 color; void main() { color = vec4(inColor.color, 1.0f); }
加入视图功能:
3D图形的表示要经过几个经典的坐标转换,首先从局部到世界坐标系,再从世界坐标系到观察坐标系。
局部坐标系—>世界坐标系—>观察坐标系
顶点着色器中:
//gl_Position = vec4(pos, 1.0f);
gl_Position = projection * view * model * vec4(pos, 1.0f);
main.cpp 中
glm::mat4 view; view = glm::translate(view, glm::vec3(0.f, 1.0f, 0.0f)); glm::mat4 proj; proj = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f); glm::mat4 model; model = glm::translate(model, glm::vec3(0.0f, 0.0f, -5.0f)); GLint nModelLoc = glGetUniformLocation(shader.getProg(), "model"); GLint nViewLoc = glGetUniformLocation(shader.getProg(), "view"); GLint nProjLoc = glGetUniformLocation(shader.getProg(), "projection"); glUniformMatrix4fv(nModelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(nProjLoc, 1, GL_FALSE, glm::value_ptr(proj));
源码下载:
http://download.csdn.net/detail/yulinxx/9769051
相关文章推荐
- OSG环境下,使用glsl的几何着色器,绘制带纹理的三角形
- OPenGL--几何着色器的应用(多实例绘制)
- OpenGL_7:用两个片段着色器和着色器程序分别画2个不同颜色的三角形
- 在unity向量空间内绘制几何(3):通过三角形重心坐标计算任意形状网格上的随机坐标点
- Android OpenGL学习笔记(二)之----三角形的绘制.
- openGL 初试 绘制三角形 和添加鼠标键盘事件
- 【OpenGL4.0】GLSL-几何着色器详解和实例(GS:Geometry Shader)
- OpenGL用着色器画绿色三角形
- 【OpenGL】理解GL_TRIANGLE_STRIP等绘制三角形序列的三种方式
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- 编写一个基于OpenGL的程序,绘制一个三角形,并分别绘制这个三角形经旋转、平移、缩放后的结果
- OpenGL 学习笔记(3)绘制几何物体
- OpenGL三角形的双面不同颜色的绘制
- 【CG】OpenGL3.3+IMGUI_绘制三角形并着色
- OpenGL 入门基础教程 —— 在第一个窗口绘制一个三角形
- 使用几何着色器来实现绘制模型轮廓线
- OpenGL深入探索——广告牌(Billboard)和几何着色器
- 【OpenGL】理解GL_TRIANGLE_STRIP等绘制三角形序列的三种方式
- [Modern OpenGL系列(三)]用OpenGL绘制一个三角形
- 使用opengl绘制三角形