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

几何着色器有意思的地方在于它可以把(一个或多个)顶点转变为完全不同的基本图形(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值