OpenGL---三角形(附带必要基础知识)

OpenGL绘制三角形 可编程渲染管线 在现代OpenGL中,我们必须定义至少一个顶点着色器和一个片段着色器(因为GPU中没有默认的顶点/片段着色器)。出于这个原因,刚开始学习现代OpenGL的时候可能会非常困难,因为在你能够渲染自己的第一个三角形之前已经需要了解一大堆知识了。 #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> //当用户改变窗口的大小的时候,视口也应该被调整。 //我们可以对窗口注册一个回调 阅读详情

!!!这篇文章的目的是教会你如何用OpenGL画一个三角形!!!

===========================================================================================

注:代码请看注释,重要的都写在注释里了。

基础知识:

一.渲染管线(我之前发表的文章)

     

二.顶点的顶点属性

  • 顶点位置(position)
  • 顶点UV坐标(UV1~UV7),一共有七组UV坐标可用
  • 顶点法线(normal)
  • 顶点切线(tangent)
  • 顶点颜色(color)
  • 等等。。。

三.OpenGL中VAO与VBO

  • 顶点数组对象:Vertex Array Object,VAO
  • 顶点缓冲对象:Vertex Buffer Object,VBO

       现在我们来解释一下顶点数组对象(VAO)和顶点缓冲对象(VBO)。

       首先解释VBO,顶点缓冲对象其实就是一块缓冲存储的引用。 可以用来开辟一块存储区间来存储顶点的各顶点属性数据。

       VAO,顶点数组对象其实是用来打包各个顶点属性的。

       比如说我有两组点,第一组点的每个点都有各自的顶点位置属性和颜色属性,第二组点的每个点都有各自的位置,顶点法线和顶点切线。如下图。当然这只是举个栗子VBO可以有多个。

   如图就是VAO和VBO的关系,VAO用于保存属性引用,VBO保存属性的具体数据。有了VAO的好处是,当渲染第一组VAO时,我突然需要渲染第二组VAO而不渲染第一组VAO时,只需解除第一组VAO的绑定,告诉OpenGL绑定第二组VAO。如果没有VAO我们需要分别解除第一组的位置和颜色然后将第二组的位置,法线和切线按需求从VBO获值然后渲染,很不方便。

 

 

===========================================================================================

OpenGL画三角形

          说明:用的是glfw和glad(glfw是用来创建窗口和监听键盘或者鼠标等事件的,glad和glew的作用差不多,都是获得函数接口引用,可以理解成glad是glew的升级版,这样我们就可以用OpenGL的API了),具体·请参考OpenGL配置。这里我们跳过配置。

第一步:初始化窗口

#include<glad\glad.h>
#include<GLFW\glfw3.h>
#include<iostream>
using namespace std;
int main()
{
	glfwInit();//初始化
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//配置GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//配置GLFW
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//使用OpenGL核心配置
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);//设置初始化的窗口长宽,显示名称,屏幕接口,第五个不知道干啥的


	if (window == nullptr)
	{
		cout << "Failed to create GLFW window" << endl;
		glfwTerminate();//terminate the glfw(end the glfw)
		return -1;
	}

	glfwMakeContextCurrent(window);//设置当前openGL上下文


	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//初始化GLAD
	{
		cout << "Failed to initialize GLAD" << endl;
		return -1;
	}

	while (!glfwWindowShouldClose(window))//渲染
	{

		glClearColor(0.27f, 0.27f, 0.27f, 1.0f);//覆盖颜色
		glClear(GL_COLOR_BUFFER_BIT);//覆盖

		glfwSwapBuffers(window);//双缓冲(替换窗口的每一个像素值)
	}
	glfwTerminate();
	return 0;

}

初始化一个窗口没啥,固定的。

 

第二步:顶点着色器(vertex shader),片元着色器(fragment shader)

  •           顶点着色器(vertex shader)
const GLchar* vertexShader_Code = 
"#version 330 core\n"//使用OpenGL3.3版本(支持可编程渲染管线版本)
"layout(location=0) in vec3 aPos;\n"//输入一个三元向量aPos(顶点位置数据),编号为0(这个数可以自己设,只要跟OpenGL中的传值得编号对应上就行,后面会讲)
"void main()\n"
"{\n"
"gl_Position=vec4(aPos.x,aPos.y,aPos.z,1.0);\n"//变成四元,这样做的目的是方便做变换,比如齐次矩阵乘法变换
"}";

 

  • 片元着色器(fragment shader)
const GLchar* fragmentShader_Code = 
"#version 330 core\n"
"out vec4 FragColor;\n"//以一个颜色值作为输出(像素的颜色)
"void main()\n"
"{\n"
"FragColor=vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"//返回颜色,个分量的值取值范围[0,1],和[0,255]一回事,就是映射范围不一样
"}";

第三步:编译着色器

//data
	int isSuccess;
	char infoLog[512];

	


	//vertexShader data
	unsigned int vertexShader;//声明一个顶点着色器的引用
	vertexShader = glCreateShader(GL_VERTEX_SHADER);//将引用指向一个顶点着色器(相当于面向对象中 new VertexShader())
	glShaderSource(vertexShader, 1,&vertexShader_Code, NULL);//加载之前写的顶点着色器
	glCompileShader(vertexShader);//编译

	/*编译是否通过*/
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		cout << "ERROR::VertexShader::Compile_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::VertexShader" << endl;
	}


/*片元着色器编译原理同上*/
	//fragmentShader Data
	unsigned int fragmentShader;
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShader_Code, NULL);
	glCompileShader(fragmentShader);
	/*编译是否通过*/
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		cout << "ERROR::FragmentShader::Compile_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::FragmentShader" << endl;
	}

 

第四步:组装渲染管线

//Shader Pragram
	unsigned int shaderProgram;//声明一个管线的引用(理解成着色器的系统也没问题)
	shaderProgram = glCreateProgram();//引用指向一个管线(相当于面向对象中 new shaderProgram())
	glAttachShader(shaderProgram, vertexShader);//组装顶点着色器
	glAttachShader(shaderProgram, fragmentShader);//组装片元着色器
	glLinkProgram(shaderProgram);//链接各个着色器成渲染管线

/*链接是否成功*/
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
		cout << "ERROR::ShaderProgram::Link_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::ShaderProgram" << endl;
		glUseProgram(shaderProgram);//使用当前的管线渲染
		glDeleteShader(vertexShader);//着色器已经加载到显卡得内存中了,cpu管理的内存中的着色器没用了,删除
		glDeleteShader(fragmentShader);////着色器已经加载到显卡得内存中了,cpu管理的内存中的着色器没用了,删除
	}

 

第五步:给顶点着色器赋初值

      1.首先是三角形的三个顶点:

//三角顶点
	float vertices[] = 
	{
		-0.5f,-0.5f,0.0f,//左下角
		 0.5f,-0.5f,0.0f,//右下角
		 0.0f, 0.5f,0.0f//顶端角
	};

注意这里的所有顶点分量都是[-1,1],这是归一化坐标,这是应为我们只是写了个最简单的画三角形的方法,跳过了物体空间坐标到世界空间坐标到视觉空间坐标到裁剪空间坐标,直接给归一化坐标空间的坐标。具体请参考渲染管线。

      2.赋值

首先先解释什么是绑定?

OpenGL中的绑定类似于将当前对象绑定后,之后的所有相关的命令都将作用于此对象。这和常见的面向对象有点区变。

就像一块画板,你绑一张画纸在上面,然后画画。画完了,将画纸解绑拿下来,原先画上的数据保留在了纸上。之后再画别的,再拿一张画纸。

//vectices data
	unsigned int VAO;//声明一个VAO对象
	unsigned int VBO;//声明一个VBO对象

	glGenVertexArrays(1, &VAO);//获得一个顶点数组对象
        glGenBuffers(1, &VBO);//获得一个顶点缓冲对象
	glBindVertexArray(VAO);//绑定一个顶点数组对象
	glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定缓冲对象
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//将之前定义的所有顶点数据装进缓冲中
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//!!!注意!!!给vertexshader赋初值。
	glEnableVertexAttribArray(0);//激活此编号数据

	glBindBuffer(GL_ARRAY_BUFFER,0);//解除VBO绑定
	glBindVertexArray(0);//解除VAO绑定

注意!!!这行代码!!!

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

还记得顶点着色器中那个layout吗?

layout(location=0) in vec3 aPos;

glVertexAttribPointer()

  • 第一个参数指定我们要配置的顶点属性。还记得我们在顶点着色器中使用layout(location = 0)定义了顶点的位置值吗?它可以把顶点属性的位置值设置为0。因为我们希望把数据传递到这一个顶点属性中,所以这里我们传入0。
  • 第二个参数指定顶点属性的大小。顶点属性是一个vec3,它由3个值组成,所以大小是3。
  • 第三个参数指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。
  • 下个参数定义我们是否希望数据被标准化(Normalize)。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。我们把它设置为GL_FALSE。
  • 第五个参数叫做步长(Stride),它告诉我们在连续的顶点属性组之间的间隔。由于下个组位置数据在3个float之后,我们把步长设置为3 * sizeof(float)。要注意的是由于我们知道这个数组是紧密排列的(在两个顶点属性之间没有空隙)我们也可以设置为0来让OpenGL决定具体步长是多少(只有当数值是紧密排列时才可用)。一旦我们有更多的顶点属性,我们就必须更小心地定义每个顶点属性之间的间隔,我们在后面会看到更多的例子(译注: 这个参数的意思简单说就是从这个属性第二次出现的地方到整个数组0位置之间有多少字节)。
  • 最后一个参数的类型是void*,所以需要我们进行这个奇怪的强制类型转换。它表示位置数据在缓冲中起始位置的偏移量(Offset)。由于位置数据在数组的开头,所以这里是0。

 

第六步:渲染

while (!glfwWindowShouldClose(window))
		{
			glfwPollEvents();//检查有没有触发事件

			glClearColor(0.27f, 0.27f, 0.27f, 1.0f);//覆盖颜色
			glClear(GL_COLOR_BUFFER_BIT);//覆盖


			glUseProgram(shaderProgram);//使用我们之前组装的渲染管线
			glBindVertexArray(VAO);//绑定我们的VAO(就像将之前画完的画重新绑在画板上,给别人看或使用)

			glDrawArrays(GL_TRIANGLES, 0, 3);//以三角模式(面覆盖),画三角形,从第0个开始,画三角形的三个点


			glfwSwapBuffers(window);//双缓冲(替换窗口的每一个像素值)
		}

除了GL_TRIANGLES外还有GL_POINTS和GL_LINE_STRIP。

  • GL_POINT,点模式绘制,请加入下面的语句,要不然太小基本看不清,想要练眼神的小伙伴请忽略!!!。
  • glPointSize(10.0f);//设置点大小
    

    GL_LINE_STRIP,线模式绘制,请加入下面的语句,要不然太细基本看不清,想要练眼神的小伙伴请忽略!!!

  • glLineWidth(10.0f);//设置线宽
    

     

最后:别忘了结束后关闭窗口

glfwTerminate();
return 0;

 

===========================================================================================

全部代码:

#include<glad\glad.h>
#include<GLFW\glfw3.h>
#include<iostream>
using namespace std;

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(window, GL_TRUE);
	}

}

//vertex shader
const GLchar* vertexShader_Code =
"#version 330 core\n"
"layout(location=0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position=vec4(aPos.x,aPos.y,aPos.z,1.0);\n"
"}";


const GLchar* fragmentShader_Code =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor=vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}";

int main()
{
	//三角顶点
	float vertices[] =
	{
		-0.5f,-0.5f,0.0f,//左下角
		0.5f,-0.5f,0.0f,//右下角
		0.0f, 0.5f,0.0f//顶端角
	};
	glfwInit();//初始化
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//配置GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//配置GLFW
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);
	glfwSetKeyCallback(window, key_callback);


	if (window == nullptr)
	{
		cout << "Failed to create GLFW window" << endl;
		glfwTerminate();//terminate the glfw(end the glfw)
		return -1;
	}

	glfwMakeContextCurrent(window);//设置当前openGL上下文


	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		cout << "Failed to initialize GLAD" << endl;
		return -1;
	}

	//data
	int isSuccess;
	char infoLog[512];




	//vertexShader data
	unsigned int vertexShader;
	vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShader_Code, NULL);
	glCompileShader(vertexShader);
	/*编译是否通过*/
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		cout << "ERROR::VertexShader::Compile_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::VertexShader" << endl;
	}

	//fragmentShader Data
	unsigned int fragmentShader;
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShader_Code, NULL);
	glCompileShader(fragmentShader);
	/*编译是否通过*/
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		cout << "ERROR::FragmentShader::Compile_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::FragmentShader" << endl;
	}

	//Shader Pragram
	unsigned int shaderProgram;
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);

	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isSuccess);
	if (!isSuccess)
	{
		glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
		cout << "ERROR::ShaderProgram::Link_failed" << infoLog << endl;
	}
	else
	{
		cout << "SUCCESS::ShaderProgram" << endl;
		glUseProgram(shaderProgram);
		glDeleteShader(vertexShader);
		glDeleteShader(fragmentShader);
	}

	//vectices data
	unsigned int VAO;
	unsigned int VBO;

	glGenVertexArrays(1, &VAO);//获得一个顶点数组对象
	glBindVertexArray(VAO);
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();//检查有没有触发事件

		glClearColor(0.27f, 0.27f, 0.27f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glUseProgram(shaderProgram);
		glBindVertexArray(VAO);

		glDrawArrays(GL_TRIANGLES, 0, 3);


		glfwSwapBuffers(window);//双缓冲(替换窗口的每一个像素值)
	}
	glfwTerminate();
	return 0;

}

 

运行结果:

结果

 

 

至此,三角形就画在了屏幕上!!!可喜可贺!!!祝小伙伴们学习愉快!!!

 

 

 

 

 

 

 

 

 

OpenGL三角形旋转平移变换 题目:已知某三角形的三顶点坐标{50.0,50.0},{150.0,50.0},{100.0,150.0}。 要求:(1)创建一个长宽分别为600、600的窗口,窗口的左上角位于屏幕坐标(100,100)处。 (2)绘制一个由上述顶点所描绘的三角形,使得三角形位于窗口的中心;对三角形进行下列的几何变换:首先使三角形沿着其中心的x轴,y轴方向缩小到原来的25%;然后绕中心旋转-90度;最后沿着x轴平移70个单位,绘制出变换后的结果。 #include <gl/glut.h> #includ 阅读详情

相关推荐

使用Opengl绘制三角形

OpenGL绘制三角形三角形的平移和旋转 三角形的平移和旋转 对三角形的三个坐标矩阵化,之后乘相应操作的矩阵得到平 移/旋转后的三角形矩阵,并用Opengl函数库进行绘制。 注意:并未使用Opengl中自带的平移与旋转函数。而是根据原理理解后写出的具体操作。 // An highlighted block // sanJiaoxing.cpp: 定义控制台应用程序的入口点。 // #inclu...

沧海一瞬 1581

【Unity Shader】顶点输入输出结构体语义

Unity 版本:2020.3.23 此教程会长期更新,欢迎大家关注!!! 博主微信号:ITComputerGraph

linda012518的博客 3612

OpenGL (一): 基础知识 & 三角形

OpenGL基础知识 &amp;amp;amp; 三角形绘制前言关于OpenGLShader绘制的大概流程绘制三角形triangle.cpp结果逐行解释后话 前言 我的环境是macOS High Sierra + Xcode 10 + glfw + glew, 相关的配置方法请参考这篇博客. 关于OpenGL我还是零基础, 所以本文所说的仅是我个人目前的理解, 所以欢迎讨论和纠错. 关于OpenGL OpenGL...

王成昊的博客 696

《Qt-OpenGL系列编程》课程学习记录(1):相关概念、VAO、VBO、绘制三角形、使用OpenGL原生方式编译链接着色器程序

大家可以去B站看课程的视频支持一下作者哈: OpenGL,Qt实现:1入门篇(已更完)_哔哩哔哩_bilibili课程相关源码、PPT、安装包,完整课程合集(1:入门篇;2:基础光照;3:模型加载;4:高级OpenGL;5:高级光照 ;程序员的数学3:线性代数):https://ke.qq.com/course/package/40726?flowToken=1041265https://www.bilibili.com/video/BV1UL411W71w 准备工作 1、关于OpenGL Ope

友善啊,朋友的博客 1602

OpenGL入门之绘制两个相连的三角形

使用不同的VAO和VBO绘制两个彼此相连的三角形 #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processI...

qq_44800780的博客 931

在macOS上学习OpenGL | 环境配置并绘制三角形

数据科学与计算机学院 徐海洋 本学习基于 LearnOpenGL (旧版)。 基本环境: MacBook Pro (15-inch, 2016) macOS High Sierra (版本10.13.3) Inter HD Graphics 530 1536 MB Xcode (Version 9.2) 使用 GLUT 的方法: 在 Xcode 项目配置里的 Build P...

HiyoungTsui 的博客 4127

OpenGL进阶 | 绘制一个三角形

OpenGL:利用shader绘制一个三角形。

该用户还没想到好的昵称的博客 1934

OpenGL三角形几何变换

#include //三角形几何变换 #include #include #include typedef double matrix3x3 [3][3]; //?????????? matrix3x3 commatrix; const double pi=3.1415926; int w=600; int h=600; class position { public: GLfloa

MILE_的专栏 2056

如何判断一点在三角形内

假定在右手坐标系中的三角形3点坐标为A,B,C,判断P是否在ABC之内 ( 主要来自 3D引擎研发QQ群(38224573 )的各位朋友的讨论 ,我仅仅算做个总结吧,特别感谢各位朋友的热情支持。 ) 方法1:三个Perplane的方法 设AB,BC,AC边上的垂直平面为Perplane[3],垂直朝向内侧的法向为n[3] 1)先根...

weixin_30902251的博客 1119

OpenGL 进阶系列02 - OpenGL绘制三角形的必要步骤

要使用 OpenGL 绘制一个三角形,通常需要几步,需要使用哪些必要的OpenGL API,这些API都是什么含义。本文以现代 OpenGL(使用着色器)为例,介绍下三角形绘制步骤。glViewport是 OpenGL 中的一个函数,用于设置视口的大小和位置。视口定义了 OpenGL 渲染的区域,即将标准设备坐标(Normalized Device Coordinates, NDC)映射到窗口坐标的区域。它的主要作用是在窗口中指定绘制图形的区域,确保图形正确显示。如果应用程序未调用glViewport。

GPU全栈博主 712

用glew,glfw实现最新的opengl3.3绘制三角代码

里面的main.cpp文件实现的是创建一个窗口,triangle.cpp文件时用索引时挥着的是一个四方形,不用索引画图是个三角形。用的是glew和glfw,所以使用之前你需要配置下环境,在vs的项目属性中添加文件里的include到头文件,lib到库的连接。或者百度glew和glfw的配置

QT使用openGL绘制一个三角形

对于opengl的学习来说,绘制一个三角形是学习一种计算机语言时的一个hello world级的入门程序,个人觉得相比主流语言的helloworld,openGL的入门确实是有一些劝退,虽然说有不错的教程,但简明与全面不可兼得,很容易面对教程中一大堆概念和术语而摸不到头脑,本文试图用“相对”简单和直观的方式让人成功的绘制出第一个三角形。对于使用QT的同学,可以直接从文末的链接下载完整代码,自己修改其中的参数观察变化,这样理解起来更快。希望能让使用QT并且想学习openGL的人踏出第一步,而不是被画一个三角.

TinyHou的博客 3998

virtuoso--DFF

27-实验课-std_cell2

qq_61440044的博客 2006

OpenGL 和 OpenGL ES基础知识

OpenGL是一个开放标准的图形API,最初由Silicon Graphics公司开发,并于1992年发布。OpenGL的目标是提供一种通用的、可扩展的、跨平台和高性能的图像渲染解决方案,使得程序员可以轻松地创建复杂的3D场景并进行交互式操作。OpenGL针对不同的平台、操作系统和硬件进行了优化,因此它非常适合于开发具有高级3D图形要求的程序,例如CAD、虚拟现实、游戏等。OpenGL ES最初是为嵌入式设备而提出的,这些设备包括智能手机、平板电脑、掌上游戏机等。

每一个不曾起舞的日子,都是对生命的辜负 2985

使用DDR4控制器实现多通道数据读写

这种高带宽对于大量的数据的应用非常重要。对于Controller/PHY Mode 的选择,我们使用Controller + PHY模式,Xilinx UltraScale/UltraScale+等高端FPGA通常包含硬核PHY,选择Controller + PHY模式可直接利用硬核,降低功耗和延迟,并且此模式的开发更易上手。在Basic页面下,首先勾选上AXI4 Interface选项,我们选用的内存接口速度为2133MHz的ddr4芯片,由于双沿触发,频率为1066MHz,那么周期应为938ps。

weixin_38828382的博客 1364

笔记本摄像头模拟监控推送RTSP流

FFmpeg软件:选择Windows builds by BtbN一个完整的跨平台解决方案,用于录制、转换和流式传输音频和视频。选择Windows版本EasyDarwin开源流媒体服务器 支持Windows、Linux、macOS平台;支持RTSP推流分发(推模式转发);支持RTSP拉流分发(拉模式转发);VLC Media Player软件:选择Windows64bit支持众多与及文件格式,并支持DVD影音光盘,VCD影音光盘及各类协议。

IT_LittleBaby的博客 3874

OpenGL画三角形

目录OpenGL窗口OpenGL三角形OpenGL画圆 OpenGL窗口 【代码总览】 glfw初始化、配置、创建窗口 glad初始化 渲染循环,检测输入并给窗口涂颜色 清理操作 // 渲染循环 while(!glfwWindowShouldClose(window)){ // 输入 processInput(window); // 渲染指令 … // 检查并调用事件,交换缓冲 glfwPollEvents(); glfwSwapBuffers(window); } 双缓冲(Double Buffer)

qq_39542170的博客 2259

自动驾驶开发者必看:nuscenes数据集23类物体标注全解析(附避坑指南)

本文深入解析nuscenes数据集的23类物体标注系统,为自动驾驶开发者提供全面的标注规范解读和实战避坑指南。涵盖多模态数据组织、类别细分规则、属性系统应用技巧以及标注质量验证方法,帮助开发者高效利用这一标杆数据集提升模型性能。

weixin_29041767的博客 256

【OpenGL】绘制三角形

实验步骤 步骤: 1-初始化: 初始化GLFW,创建窗口,初始化GLAD,创建视口 2-数据处理: 给定顶点数据,生成并绑定VAO&VBO(准备再GPU中进行处理),设置顶点属性指针(本质上就是告诉OpenGL如何处理数据)。 3-着色器: 给出顶点和片段着色器,然后链接为着色器程序,渲染时使用着色器程序。 4-渲染: 清空缓冲,使用着色器程序,绘制三角形,交换缓冲区并检查触发事件(比如键...

Do Better 1152

大模型技术全景与核心概念解析:从基础原理到AI智能体架构(实时更新中)

本文系统解析了大模型技术的核心概念与架构。首先介绍了LLM(大语言模型)、LLMOps(模型运维)、AIGC(生成内容)、AGI(通用AI)等基础概念,重点阐述了大模型的工作原理,包括预处理、推理和后处理三个阶段。深入讲解了Token分词、FLOPs计算、Embedding向量表示等关键技术,并分析了LoRA微调、MoE架构等前沿方法。文章还探讨了AI智能体的发展前景,为理解大模型技术提供了全景视角。

算法工程师 1238

Vue - 详细实现低代码平台,支持拖曳式可视化生成应用软件功能,用户通过拖拽元素、搭积木的方式创建应用(适合迭代的基础架构、低代码平台)

Vue低代码平台-拖曳式拖拉拽可视化生成应用软件,拖拽式低代码数据可视化开发平台,vue实现拖拽,拖拽式Vue组件代码生成平台,基于vue的可视化拖拽代码生成工具,Vue实现可拖拽组件的方法,一个低代码平台的前端部分,靠拖拉拽生成页面。Vue技术栈从零实现低代码可视化搭建平台示例,低代码轮子,通过拖拽就可生成Vue代码的平台来了,vue低代码平台开发相关比低代码更强大的零代码开发平台,这款低代码SAAS数据可视化工具,拖拽生成大屏。vue实现拖拽效果,Vue自由拖拽缩放组件,自定义组件(文本、图片

🏆 前端领域优质创作者 1万+

三、OpenGL中三角形的绘制

本文主要介绍如何使用OPenGL创建一个三角形。

TechNomad的博客 1197

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【OpenGL】十三、OpenGL 绘制三角形 ( 绘制单个三角形 | 三角形绘制顺序 | 绘制多个三角形 )

一、绘制三角形、 二、三角形绘制顺序、 1、绘制正面、 2、三个点逆时针方向排列、 3、三个点顺时针方向排列、 4、设置点的正面方向、 三、绘制多个三角形、 四、相关资源、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 6852

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上一篇: 渲染基础-渲染管线(Render-pipeline)
下一篇: Vulkan::0.0::开始于VulKanSDK(Getting Started with the Vulkan SDK)
FuXiii
博客等级 码龄9年 89粉丝 21原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值