您的位置:首页 > 运维架构

OpenGL 几何着色器 传入点,绘制三角形

2017-03-02 16:10 399 查看
几何着色器有意思的地方在于它可以把(一个或多个)顶点转变为完全不同的基本图形(primitive),从而生成比原来多得多的顶点。



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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opengl