首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在OpenGl中旋转正方形

在OpenGL中,要旋转一个正方形可以使用以下步骤:

  1. 创建一个窗口和渲染上下文。
  2. 设置视口和投影矩阵,以确保正方形在窗口中正确显示。
  3. 定义正方形的顶点坐标和颜色。
  4. 创建一个顶点缓冲对象(VBO)来存储正方形的顶点数据。
  5. 创建一个顶点数组对象(VAO)来管理顶点属性状态。
  6. 编写一个顶点着色器和片段着色器来处理正方形的渲染。
  7. 编译和链接着色器程序。
  8. 在渲染循环中,绑定VAO和VBO,并使用着色器程序进行渲染。
  9. 在每一帧中,通过修改模型矩阵来实现正方形的旋转。

以下是一个示例的代码片段:

顶点着色器代码:

代码语言:txt
复制
#version 330 core
layout (location = 0) in vec3 aPosition;
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;

void main()
{
    gl_Position = uProjection * uView * uModel * vec4(aPosition, 1.0);
}

片段着色器代码:

代码语言:txt
复制
#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 使用红色作为正方形的颜色
}

C++代码:

代码语言:txt
复制
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>

// 正方形的顶点坐标
float vertices[] = {
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    0.5f, 0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f
};

// 正方形的索引
unsigned int indices[] = {
    0, 1, 2,
    2, 3, 0
};

// 初始化OpenGL窗口和上下文
void initGLFW()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}

// 创建窗口和上下文
GLFWwindow* createWindow(int width, int height, const char* title)
{
    GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        exit(-1);
    }
    glfwMakeContextCurrent(window);
    return window;
}

// 初始化OpenGL函数指针
void initGLAD()
{
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        exit(-1);
    }
}

// 创建顶点缓冲对象(VBO)
unsigned int createVBO()
{
    unsigned int vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    return vbo;
}

// 创建顶点数组对象(VAO)
unsigned int createVAO()
{
    unsigned int vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    return vao;
}

// 绑定顶点属性指针
void bindVertexAttributes()
{
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

// 创建索引缓冲对象(EBO)
unsigned int createEBO()
{
    unsigned int ebo;
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    return ebo;
}

// 编译和链接着色器程序
unsigned int createShaderProgram()
{
    // 编译顶点着色器
    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
    glCompileShader(vertexShader);
    
    // 检查顶点着色器是否编译成功
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "Failed to compile vertex shader" << std::endl;
        exit(-1);
    }
    
    // 编译片段着色器
    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderCode, NULL);
    glCompileShader(fragmentShader);
    
    // 检查片段着色器是否编译成功
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "Failed to compile fragment shader" << std::endl;
        exit(-1);
    }
    
    // 创建着色器程序并链接着色器
    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    
    // 检查着色器程序是否链接成功
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success)
    {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "Failed to link shader program" << std::endl;
        exit(-1);
    }
    
    // 删除着色器对象
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    
    return shaderProgram;
}

// 渲染循环
void renderLoop(GLFWwindow* window, unsigned int vao, unsigned int ebo, unsigned int shaderProgram)
{
    while (!glfwWindowShouldClose(window))
    {
        // 处理输入事件
        processInput(window);
        
        // 清空屏幕颜色
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        
        // 使用着色器程序
        glUseProgram(shaderProgram);
        
        // 更新模型矩阵以实现旋转
        float angle = glfwGetTime() * 50.0f;
        glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0f, 0.0f, 1.0f));
        unsigned int modelLocation = glGetUniformLocation(shaderProgram, "uModel");
        glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model));
        
        // 绑定顶点数组对象(VAO)和索引缓冲对象(EBO)
        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        
        // 绘制正方形
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        
        // 交换缓冲区并查询事件
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

int main()
{
    // 初始化GLFW
    initGLFW();
    
    // 创建窗口和上下文
    GLFWwindow* window = createWindow(800, 600, "OpenGL");
    
    // 初始化GLAD
    initGLAD();
    
    // 创建顶点缓冲对象(VBO)
    unsigned int vbo = createVBO();
    
    // 创建顶点数组对象(VAO)
    unsigned int vao = createVAO();
    
    // 绑定顶点属性指针
    bindVertexAttributes();
    
    // 创建索引缓冲对象(EBO)
    unsigned int ebo = createEBO();
    
    // 编译和链接着色器程序
    unsigned int shaderProgram = createShaderProgram();
    
    // 进入渲染循环
    renderLoop(window, vao, ebo, shaderProgram);
    
    // 清理资源
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &ebo);
    glDeleteProgram(shaderProgram);
    
    // 终止GLFW
    glfwTerminate();
    
    return 0;
}

这个例子演示了如何在OpenGL中旋转一个正方形。你可以根据自己的需要自定义顶点位置、顶点颜色、旋转角度等参数。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • OpenGL ES for Android 绘制旋转的地球

    No 图 No Code,上面旋转的地球是不是很酷炫,下面就让我们开始说说如何绘制旋转地球吧?绘制旋转地球需要3个步骤: 计算球体顶点数据。 地球纹理贴图。 通过MVP矩阵旋转地球。...计算球体顶点数据 我们知道OpenGL中最基本的图元是三角形,任何复杂的图形都可以分解为一个个的三角形,球体也不例外,假设球体上有“经纬度”,通过“经纬度”将球体分割为一个个的四边形,如下图: ?...在把这些四边形分割为2个三角形,所以绘制球体的关键是计算“经纬度”相交的点的坐标。...R.drawable.earth) textureId = GLTools.loadTexture(bitmap) } GLTools.loadTexture为封装的工具类方法,在OpenGL...ES 绘制纹理文章中已经详细介绍,图片纹理的相关内容也可以参考此文章。

    1.7K20

    OpenGL ES for Android 视频缩放、旋转、平移

    在上一篇文章中我们介绍了使用OpenGL ES 播放视频,在末尾提到如果渲染视频的窗口宽高比和视频宽高比不一致会导致视频拉伸,这篇文章将会介绍如何通过视频的缩放来解决这个问题。...我们在OpenGL ES 播放视频的基础进行修改,修改顶点shader attribute vec4 a_Position; attribute vec2 a_TexCoordinate; varying...中获取,视频的宽高需要给meidaplay添加OnVideoSizeChangedListener回调,由于视频的播放是在onSurfaceCreated中调用且这2个回调都是异步的,因此无法判断先后顺序...,因此在这2个回调中都增加判断,只有当视频和渲染窗口的宽高都获取到才计算MVP矩阵,或者我们也可以在onSurfaceChanged中调用视频播放,这样就可以只在OnVideoSizeChangedListener...视频的旋转、平移和缩放是一样的,我们只需要对矩阵进行相应的操作,比如将视频旋转45度,代码如下: Matrix.rotateM(modelMatrix,0,45F,0F,0F,1F) 效果如下: ?

    2.8K20

    OpenGL(五)-- OpenGL中矩阵的变换OpenGL(五)-- OpenGL中矩阵的变换

    OpenGL(五)-- OpenGL中矩阵的变换 前言 照常提出几个问题,希望通过阅读可以找到答案。 对物体3维的2维投影进行位移,有几种方式? 模型视图矩阵代表了什么?...世界坐标系 WORLD SPACE称为世界坐标系,记录物体在坐标系中的位置; 世界坐标系是由原点经过模型矩阵(Model Matrix)通过矩阵相乘变换得来的。 3....具体可以想象移动的是物体的每一个点,在旋转之后物体的每一个点都的方向向量都会旋转,之后平移就会按照方向向量来进行移动 先平移不会修改物体额方向向量,所以旋转就会得到不同的效果。...中涉及到的矩阵变换 在OpenGL中矩阵的计算方式 // 矩阵计算 m3dMatrixMultiply44(ModelViewMatrix(模型视图矩阵),ViewMatrix(观察者矩阵), ModelMatrix...如果想要了解具体矩阵是如何计算的:3D数学 矩阵知识 矩阵栈 在计算时会发现这种计算会导致物体唯一无法重置,为了解决这种问题OpenGL提出了矩阵栈的概念。栈这个概念应该是很熟悉了吧!

    2.3K11

    OpenGL与OpenGL在移动端的应用

    OpenGL在移动端的表现形式为OpenGLES,OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计...二.坐标系统 开始绘制图形之前,我们必须先给OpenGL输入一些顶点数据。OpenGL是一个3D图形库,所以我们在OpenGL中指定的所有坐标都是3D坐标(x、y和z)。...OpenGL不是简单地把所有的3D坐标变换为屏幕上的2D像素;OpenGL仅当3D坐标在3个轴(x、y和z)上都为-1.0到1.0的范围内时才处理它。...image.png 我们可以看到图中茶壶先旋转再平移与先平移再旋转最终的结果是不一样的,因为它都是基于物体本身,学过线性代数我们会知道矩阵乘法不满足交换律。...接着对装配好的图元进行裁剪(clip):保留完全在视锥体中的图元,丢弃完全不在视锥体中的图元,对一半在一半不在的图元进行裁剪;接着再对在视锥体中的图元进行剔除处理(cull):这个过程可编码来决定是剔除正面

    2.7K30

    实验3 OpenGL几何变换

    1.实验目的: 理解掌握一个OpenGL程序平移、旋转、缩放变换的方法。...2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法; (2)根据示范代码,尝试完成实验作业; 3.实验原理: (1)OpenGL下的几何变换 在OpenGL...由于矩阵乘法满足结合率,((RT)v) = R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即:实际变换的顺序与代码中写的顺序是相反的。...(视口变换) 这些,都可以在OpenGL中实现。 从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。...OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。

    1.2K20

    【OpenGL】二十、OpenGL 矩阵变换 ( 矩阵缩放变换 | 矩阵旋转变换 | 矩阵平移变换 )

    文章目录 一、绘制三角形 二、选中矩阵设置 三、矩阵缩放变换 四、矩阵旋转变换 五、矩阵平移变换 六、相关资源 一、绘制三角形 ---- 先绘制一个三角形 , 矩阵变换的主题就是该三角形 ; OpenGL...三角形绘制相关参考 【OpenGL】十三、OpenGL 绘制三角形 ( 绘制单个三角形 | 三角形绘制顺序 | 绘制多个三角形 ) 博客 ; 代码示例 : // 渲染场景 // 清除缓冲区...【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 ) 博客中简单介绍了...投影矩阵 和 模型视图矩阵 ; 进行 平移 , 缩放 , 旋转 等矩阵操作 , 主要针对 模型视图矩阵 进行操作 ; 在进行 OpenGL 环境渲染时 , 选中了 GL_MODELVIEW 模型视图矩阵后..., 就开始了渲染 , 后面操作的矩阵都是针对该 GL_MODELVIEW 矩阵的 ; 下面的代码是设置矩阵的代码 , 之后就开始了 OpenGL 模型渲染 , 也就是说模型渲染过程中 , 全程都选中了模型矩阵

    3.7K00

    必会算法:在旋转有序的数组中搜索

    大家好,我是戴先生 今天给大家介绍一下如何利用玄学二分法找出目标值元素 想直奔主题的可直接看思路2 ##题目 整数数组 nums 按升序排列,数组中的值互不相同 在传递给函数之前,nums...: 将数组第一个元素挪到最后的操作,称之为一次旋转 现将nums进行了若干次旋转 给你 旋转后 的数组 nums 和一个整数 target 如果 nums 中存在这个目标值 target 则返回它的下标...n次之后就是这样的 所以我们的目标就是在这样的数组里边找目标值 可以非常清晰的看到 第二段的所有值都是小于第一段的值 这样思路就非常清晰了 在二分查找的时候可以很容易判断出 当前的中位数是在第一段还是第二段中...最终问题会简化为在一个增序数据中的普通二分查找 我们用数组[1,2,3,4,5,6,7,8,9]举例说明 target目标值为7 3次旋转之后是这个样子 使用二分查找的话,首先还是先找到中位数 即下表为...(0+8)/2=4 nums[4] = 8 此时8>nums[start=0]=4的 同时8>target=7 所以可以判断出 此时mid=4是处在第一段中的 而且目标值在mid=4的前边 此时,查找就简化为了在增序数据中的查找了

    2.8K20

    OpenGL (二)--OpenGL中那些晦涩难懂的名词、动词解析OpenGL (二)--OpenGL中那些晦涩难懂的名词、动词解析

    图元 首先需要明确一个概念图元,在OpenGl中图元包含:点、线、三角形。也就是说我们看到的任何图形都是由这三个基本元素组成的。...将顶点数据保存到内存中,就称为顶点数组。 将顶点数据保存到GPU的显存中,就称为顶点缓存区 ? 管线 从图片到显示在屏幕上需要一个过程。...这就是OpenGL中一个完成的管线流程。 在最后一步测试与混合中,实际进行了以下几步的操作。 ? 固定管线 在OpenGL的早期,提供了很多API来帮助开发者快速完成渲染流程。...OpenGL中已经提供了一些固定的混合算法,但是平时开发中也会使用自定义片元着色器来完成,但是效率会比固定混合算法差一些。...变换矩阵 在OpenGL中想要图形发生平移、缩放、旋转就需要变换矩阵进行计算。 投影矩阵 在OpenGL中想要3D坐标转换为2D坐标,就需要投影矩阵进行计算。

    1.1K21

    第4章代码-图形几何变换

    目录 4.4 编程实例——三角形与矩形变换及动画 4.4.1 自定义矩阵变换实例——三角形变换 4.4.2 OpenGL几何变换实例——矩形变换 4.4.3 变换应用实例——正方形旋转动画 4.4 编程实例...- p1.z); /* 通过平移-旋转-平移复合变换序列完成任意轴的旋转(注意OpenGL中的反序表示)*/ glTranslatef (p1.x, p1.y, p1.z); /...glutDisplayFunc(myDisplay); glutReshapeFunc(Reshape); glutMainLoop(); } 4.4.3 变换应用实例——正方形旋转动画...= 0.5f; //正方形边长 GLfloat theta = 0.0f; //旋转初始角度值 void myDisplay() { glClearColor(0.8f, 0.8f, 0.8f,...400);//设置显示窗口大小 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//设置显示模式为双缓冲和RGB彩色模式) glutCreateWindow("旋转的正方形

    67830

    实验4 二维几何变换

    2.实验内容: 根据示范代码1,使用OpenGL平移、旋转、缩放变换函数来改写代码实现所要求的功能。示范代码1的代码运行结果为图1。...3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。...由于矩阵乘法满足结合率,((RT)v) = R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即:实际变换的顺序与代码中写的顺序是相反的。...(视口变换) 这些,都可以在OpenGL中实现。 从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。...OpenGL规定堆栈至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。 通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便、更快速。

    1.1K20

    【OpenGL】二十三、OpenGL 光照中的法线原理

    如果 入射光线与法线角度等于 90 度 , 就不会产生反射 , 此时点是黑色的 ; 如果 入射光线与法线角度大于 90 度 , 也不会产生反射 , 此时点是黑色的 ; 因此法线指向的角度不同 , 屏幕中绘制的点的颜色也是不同的...; 法线一定程度上决定这个点是否反射光 , 也就是是否在屏幕上绘制指定的颜色值 ; 下面的球法线垂直与球平面 , 当光照从右上角方向打过来时 , 亮的地方就是法线与入射光夹角小于 90 的点 ( 正光面...) , 黑的地方就是法线与入射光夹角大于等于 90 度的点 ( 背光面 ) ; 在可编程管线中 , 决定某个点是否在 正光面 还是 背光面 的判定方法 : 将改点与光源连线 , 计算该连线与法线的夹角...材质颜色值 相乘 , 再乘以反射率 , 就是反射出去的光 , 这也是模型表面呈现的颜色值 ; 二、相关资源 ---- GitHub 地址 : https://github.com/han1202012/OpenGL

    82801

    OpenGl读取导入3D模型并且添加鼠标移动旋转显示

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11543828.html 最近实习要用到opengl库就是跟opencv 有点像的那个,然后下了一个...https://blog.csdn.net/ding_programmer/article/details/91049357 下载之后,复制代码到自己的项目运行  改一个那个我定义的路径,然后还要配置一下opengl...可以实现旋转: ? 旋转之后: ? 可以实现缩放: ? 缩小: ? 可以实现平移: ?...就可以跟踪Z轴上的像素,那么它只有在前面没有东西的情况下才会绘制这个像素,在绘制3d时,最好启用,视觉效果会比较真实 //glEnable(GL_TEXTURE_2D); //...w, GLint h) { glViewport(0, 0, static_cast(w), static_cast(h));//跨平台进行强制类型转换 在c

    2.7K30
    领券