2018级山东大学计算机学院图形学实验汇总

前言

本文为计算机图形学实验汇总,实验采用glad与glfw编写,代码还有很多不完善的地方。不要抄袭,代码仅供参考。

  1. 这些实验完成时间跨度较大,部分代码进行了二次重构,但是实验内可能仍然有不同的写法,希望参考代码后,自己编写的代码可以对其进行完善与统一。可以将画线、画多边形等操作合理封装,形成一个完善的图形学头文件甚至名称空间,这样对后续实验的进行有很大的帮助,同时代码也会显得更加美观。
  2. 由于我是第一次使用glfw,部分用法可能不太合理或有更好的解决方案。

glfw的学习网站是 LearnOpenGl , 很多人使用的是glut,虽然glfw的学习成本比glut要大一些(亿些),但是glut是已经停止维护20多年了,现在最新的用法是glfw+glad,既然要学OpenGL,那么为什么不学最新的?在实际写代码的过程中,你会发现图形学实验还是很有意思的,希望大家认真对待。

想要完成下面代码,基本上入门部分学一半就够了, 更高级的如果有兴趣可以学一下,学习网站最后的实验也可以做一下,成品看起来还是很好玩的。

笔记当时都是用latex写的,很多语句csdn不支持,因此大部分为截图(懒得整理了)。

注意:我是在mac上运行的代码,编译器采用的是clion,其他环境应该也没啥问题。

可以借鉴,禁止抄袭

实验基本要求

作业题目内容要求
画线算法(判别式)支持用户交互输入/移动/修改两端点;算法遵循“判别式”的精神,没有取整操作,没有浮点数的乘法。
Liang-Barsky裁剪算法支持用户交互输入/移动/修改两端点;算法遵循“直线段参数化”的精神,实时画出直线。请注意:画线的命令可以调用现成的API(而不是逐像素地画)。
多边形被矩阵窗口裁剪窗口可固定;支持用户输入任意复杂多边形;输出的多边形边界必须完整(可不填充);不包括重复顶点和重复边。
扫描线填充多边形支持用户输入任意复杂多边形
交互Bezier曲线支持insert/delete/move控制点; 基于De Casteljau’s割角算法;同时画出控制顶点/控制多边形/样条曲线。
交互B样条基于de boor割角算法;支持insert/delete/move控制点;支持修改阶数;同时画出控制顶点/控制多边形/样条曲线。
交互显示测地距离场基于libigl显示一个三维模型,用鼠标选中一个顶点,使用纹理图片显示距离场效果。距离场算法代码请使用这个,如果你不懂,请阅读readme

程序的演示方法在代码中很容易看出。

公共代码相关

CmakeList.txt
cmake_minimum_required(VERSION 3.14)
project(ComputerGraphics)

set(CMAKE_CXX_STANDARD 14)

# 添加头文件
set(GLFW_H /usr/local/Cellar/glfw/3.3.2/include/GLFW)
set(GLAD_H /usr/local/include/glad)
set(KH_H /usr/local/include/KHR)
include_directories(${GLFW_H} ${GLAD_H} ${KH_H})

find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})

find_package(GLUT REQUIRED)
include_directories(${GLUT_INCLUDE_DIR})

# 添加目标链接
#set(GLEW_LINK /usr/local/Cellar/glew/2.1.0_1/lib/libGLEW.2.1.0.dylib)
set(GLFW_LINK /usr/local/Cellar/glfw/3.3.2/lib/libglfw.3.dylib)
set(CMAKE_CXX_FLAGS "-g -Wall")

link_libraries(${OPENGL} ${GLFW_LINK})

# 执行编译命令
set(SOURCE_FILES0 "glad.c" LearnOpenGl.cpp)
set(SOURCE_FILES1 "glad.c" LearnOpenGL_template.cpp)
set(SOURCE_FILES2 "glad.c" LiangBarsky.cpp)
set(SOURCE_FILES3 "glad.c" Scan_Line.cpp)
set(SOURCE_FILES4 "glad.c" Bezier.cpp)
set(SOURCE_FILES5 "glad.c" Bresenham.cpp)
set(SOURCE_FILES6 "glad.c" B_spline.cpp)
set(SOURCE_FILES7 "glad.c" SutherlandHodgeman.cpp)
set(SOURCE_FILES8 "glad.c" DistanceField.cpp)
set(SOURCE_FILES9 "glad.c" test9.cpp)

add_executable(LearnOpenGl ${SOURCE_FILES0} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(LearnOpenGL_template ${SOURCE_FILES1} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(LiangBarsky ${SOURCE_FILES2} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Scan_Line ${SOURCE_FILES3} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Bezier ${SOURCE_FILES4} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(Bresenham ${SOURCE_FILES5} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(B_spline ${SOURCE_FILES6} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(SutherlandHodgeman ${SOURCE_FILES7} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(DistanceField ${SOURCE_FILES8} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
add_executable(test9 ${SOURCE_FILES9} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})

if (APPLE)
    target_link_libraries(LearnOpenGl "-framework OpenGL" "-framework GLUT")
    target_link_libraries(LearnOpenGL_template "-framework OpenGL" "-framework GLUT")
    target_link_libraries(LiangBarsky "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Scan_Line "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Bezier "-framework OpenGL" "-framework GLUT")
    target_link_libraries(Bresenham "-framework OpenGL" "-framework GLUT")
    target_link_libraries(B_spline "-framework OpenGL" "-framework GLUT")
    target_link_libraries(SutherlandHodgeman "-framework OpenGL" "-framework GLUT")
    target_link_libraries(DistanceField "-framework OpenGL" "-framework GLUT")
    target_link_libraries(test9 "-framework OpenGL" "-framework GLUT")
endif()
顶点着色器代码:shader.vs
#version 330 core
layout (location = 0) in vec3 aPos;

out vec3 ourColor;

void main(){
    gl_Position = vec4(aPos, 1.0);
}
片段着色器代码:shader.fs
#version 330 core

out vec4 FragColor;
uniform vec4 ourColor;

void main(){
    FragColor = ourColor;
}
着色器类:shader.h
#ifndef COMPUTERGRAPHICS_SHADER_H
#define COMPUTERGRAPHICS_SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;

class Shader{
public:
    unsigned int ID;//程序ID
    Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr){//顶点着色器,片段着色器,几何着色器
        string vertexCode;//存储着色器代码
        string fragmentCode;
        string geometryCode;
        ifstream vShaderFile;
        ifstream fShaderFile;
        ifstream gShaderFile;
        //保证如果打开失败可以抛出异常
        vShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
        fShaderFile.exceptions (ifstream::failbit | ifstream::badbit);
        gShaderFile.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();

            vertexCode = vShaderStream.str();
            fragmentCode = fShaderStream.str();

            if(geometryPath != nullptr){
                gShaderFile.open(geometryPath);
                stringstream gShaderStream;
                gShaderStream << gShaderFile.rdbuf();
                gShaderFile.close();
                geometryCode = gShaderStream.str();
            }
        }
        catch (ifstream::failure& e){
            cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl;
        }
        const char* vShaderCode = vertexCode.c_str();
        const char * fShaderCode = fragmentCode.c_str();

        //创建和编译顶点着色器
        unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);//创建一个顶点着色器
        glShaderSource(vertex, 1, &vShaderCode, nullptr);//将顶点着色器源码附加到着色器对象上
        glCompileShader(vertex);//编译这个着色器对象
        checkCompileErrors(vertex, "VERTEX");//检查错误
        unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);//创建一个片段着色器
        glShaderSource(fragment, 1, &fShaderCode, nullptr);//将片段着色器源码附加到着色器对象上
        glCompileShader(fragment);//编译这个着色器对象
        checkCompileErrors(fragment, "FRAGMENT");//检查错误
        unsigned int geometry;
        if(geometryPath != nullptr){//如果有几何着色器,则重复上述步骤
            const char * gShaderCode = geometryCode.c_str();
            geometry = glCreateShader(GL_GEOMETRY_SHADER);
            glShaderSource(geometry, 1, &gShaderCode, nullptr);
            glCompileShader(geometry);
            checkCompileErrors(geometry, "GEOMETRY");
        }
        ID = glCreateProgram();//创建一个着色器程序对象
        glAttachShader(ID, vertex);//将顶点着色器对象附加到程序对象上
        glAttachShader(ID, fragment);//将片段着色器对象附加到程序对象上
        if(geometryPath != nullptr)
            glAttachShader(ID, geometry);
        glLinkProgram(ID);//链接着色器
        checkCompileErrors(ID, "PROGRAM");//检查链接错误

        glDeleteShader(vertex);//删除之前不需要的着色器对象
        glDeleteShader(fragment);
        if(geometryPath != nullptr)
            glDeleteShader(geometry);

    }
    void use(){//激活着色器对象
        glUseProgram(ID);
    }
    //uniform工具函数
    void setBool(const string &name, bool value) const{//name是一个uniform的值
        glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
    }
    void setInt(const string &name, int value) const{
        glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
    }
    void setFloat(const string &name, float value) const{
        glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
    }
    void setVec2(const string &name, const glm::vec2 &value) const{
        glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec2(const string &name, float x, float y) const{
        glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
    }
    void setVec3(const string &name, const glm::vec3 &value) const{
        glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec3(const string &name, float x, float y, float z) const{
        glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
    }
    void setVec4(const string &name, const glm::vec4 &value) const{
        glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec4(const string &name, float x, float y, float z, float w){
        glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
    }
    void setMat2(const string &name, const glm::mat2 &mat) const{
        glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    void setMat3(const string &name, const glm::mat3 &mat) const{
        glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    void setMat4(const string &name, const glm::mat4 &mat) const{
        glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }

private:
    void checkCompileErrors(GLuint shader, string type){//错误检查
        GLint success;
        GLchar infoLog[1024];
        if(type != "PROGRAM"){
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if(!success){
                glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
                cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << endl;
            }
        }
        else{
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if(!success){
                glGetProgramInfoLog(shader, 1024, nullptr, infoLog);
                cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << endl;
            }
        }
    }
};

#endif //COMPUTERGRAPHICS_SHADER_H
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CSDN是一个知名的技术社区平台,而山东大学计算机图形实验则是该计算机专业的一门实践性课程。 在计算机图形实验中,生将有机会习和应用计算机图形的基本原理、算法和技术,以及图像处理和 三维图形的渲染等相关知识。通过这门实验课程,生可以深入了解计算机图形的概念、理论和应用,提升自己的实践能力和解决问题的能力。 CSDN作为一个技术社区平台,与山东大学计算机图形实验也存在一定的关联。通过在CSDN上发表和分享个人在计算机图形实验中的经验、习心得和技术总结,生们可以扩展自己的影响力,与其他专业人士进行交流和合作,获取更多实践经验和习资源。 同时,CSDN还提供了丰富的技术文档、资讯、教程等资源,通过在CSDN上搜索相关的计算机图形实验资料,生们能够快速获取到最新的行业动态和术发展,帮助他们更好地理解和应用计算机图形的知识。 总之,CSDN和山东大学计算机图形实验相互促进,共同为生的习和成长提供支持和帮助。通过积极利用CSDN的资源和平台,生们可以在实践中不断提升自己的技能,为今后的习和工作打下坚实的基础。 ### 回答2: csdn是一个知识分享平台,而山东大学计算机图形实验是该计算机系开设的一门实践课程。这门实验课程旨在教授生有关计算机图形的基本理论和实际操作的知识。 在山东大学计算机图形实验中,生将习如何使用计算机图形的技术和工具来创建和处理图像、动画和虚拟现实等内容。课程涵盖了计算机图形的基本概念、算法和应用。生将通过编程和实践项目来加深对这些概念和技术的理解。 在实验课程中,生将习使用常见的图形库和软件工具,如OpenGL、CUDA等。通过使用这些工具,他们将能够实现各种图形技术,如三维渲染、光影处理、动画制作等。此外,他们还将习如何应用图形知识来解决实际问题,如计算机辅助设计、医图像处理等。 在教过程中,教师将为生提供必要的理论知识,并指导他们完成实践项目。生将通过小组合作和个人努力来完成各种编程任务和项目。课程结束时,生将具备良好的计算机图形技能,并能够独立进行图形相关的项目和研究。 通过参加山东大学计算机图形实验生将能够深入了解图形的基本原理和应用,掌握常用的图形工具和技术,培养解决实际问题的能力。这门实验课程将为生的术和职业发展提供强有力的支持。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值