山东大学计算机科学与技术图形学实验索引

前言

图形学是计算机中很有意思的一块内容,在影视、游戏行业有着大量的应用,图形学的实验也十分有趣,建议仔细研究。

要学习图形学在我看来,一方面是图形学理论的学习,这个就不得不提到Games101 ,老师对此也是大加赞赏,也是少有的不用开倍速学习的网课。

其二是图形学API的学习,这门课使用的是OpenGL,大多同学使用的glut,确实glut比较简单,容易上手,不过glut也是十分古老了,建议使用最新的glfw和glad,可以在learnOpenGL 网站上进行学习,就目前而言,完成以下实验仅需看完入门部分即可。

实验过程中也参考了一位名叫龙征天学长的代码,并且对一些没有实现的功能进行了实现。

实验内容

实验题目内容
直线与画圆算法实现DDA和Bresenham算法绘制直线和中点画圆法
裁剪算法实现Liang-Barsky直线裁剪算法
光栅化实现多边形填充、Z-buffering、反走样算法

关于代码框架(非最终版本)

使用OpenGL其实可以有一个大体的框架,实验过程中只需要在该框架上进行搭建即可,以下就是后面每个实验需要用到的公共代码(其实主要是着色器),如果现在不知道什么是着色器可以看看之前提到的learnOpenGL入门部分。

片段着色器

shader.fs

#version 330 core
out vec4 FragColor;

uniform vec4 ourColor;

void main()
{
    FragColor = ourColor;
}

顶点着色器

shader.vs

#version 330 core
layout (location = 0) in vec3 aPos;
out vec3 outColor;
void main()
{
    gl_Position = vec4(aPos, 1.0);
}

着色器类

shader.h

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<fstream>
#include<sstream>
#include<cmath>
#include "glad/glad.h"
#include"GLFW/glfw3.h"
#ifndef SHADER_H
#define SHADER_H
using namespace std;
class Shader {
public:
    //程序ID
    unsigned int ID;

    //构造器读取并构建着色器
    Shader(const GLchar* vertexPath, const GLchar* fragmentPath);

    //使用/激活程序
    void use() const;
    //uniform工具函数
    void setBool(const string & name, bool value) const;
    void setInt(const string & name, int value) const;
    void setFloat(const string & name, float value) const;
    void setVec4(const string &name, float x, float y, float z, float w) const;

private:
    char infoLog[512]{};
};


#endif //SHADER_H

shader.cpp

#include "shader.h"
Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath) {
    //从文件获取顶点/片段着色器
    string vertexCode;
    string fragmentCode;
    ifstream vShaderFile;
    ifstream fShaderFile;

    //抛出异常
    vShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
    fShaderFile.exceptions (ifstream::failbit | ifstream::badbit);

    try{
        //打开文件
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        stringstream vShaderStream,fShaderStream;
        //读取文件缓冲内容到数据流
        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();
        //关闭文件处理器
        vShaderFile.close();
        fShaderFile.close();
        //转换数据流到String
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
    }
    catch(ifstream::failure e){
        cout<<"ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ"<<endl;
    }

    const char* vShaderCode = vertexCode.c_str();
    const char* fShaderCode = fragmentCode.c_str();

    //编译着色器
    unsigned int vertex,fragment;
    int success;

    //顶点着色器
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, nullptr);
    glCompileShader(vertex);
    // 打印编译错误(如果有的话)
    glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
    if(!success)
    {
        glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    };


    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment,1,&fShaderCode, nullptr);
    glCompileShader(fragment);

    glGetShaderiv(fragment,GL_COMPILE_STATUS,&success);
    if(!success){
        glGetShaderInfoLog(fragment,512, nullptr,infoLog);
        cout<<"ERROR::SHADER::FRAGMENT::COMPILATION_FILED\n"<<infoLog<<endl;
    }


    //着色器程序
    ID = glCreateProgram();

    //链接着色器
    glAttachShader(ID,vertex);
    glAttachShader(ID,fragment);
    glLinkProgram(ID);

    //判断连接是否成功
    glGetProgramiv(ID,GL_LINK_STATUS,&success);
    if(!success){
        glGetProgramInfoLog(ID,512, nullptr,infoLog);
        cout<<"ERROR::SHADER::PROGRAM::COMPILATION_FILED\n"<<infoLog<<endl;
    }

    //连接完成后删除着色器对象
    glDeleteShader(vertex);
    glDeleteShader(fragment);
}

void Shader::use() const {
    glUseProgram(ID);
}

void Shader::setBool(const string &name, bool value) const {
    glUniform1i(glGetUniformLocation(ID,name.c_str()),(int)value);
}

void Shader::setInt(const std::string &name, int value) const
{
    glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const std::string &name, float value) const
{
    glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setVec4(const string &name, float x, float y, float z, float w) const {
    glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值