错误 C2338 ‘radians‘ only accept floating-point input
系列文章目录
文章目录
系列文章目录前言一、错误原因二、解决运行效果代码源码-
前言
错误 C2338 ‘radians’ only accept floating-point input
一、错误原因
从上图中看出glm::radians是模板实现,所以(glm::radians(40)函数参数必须是float类型
二、解决
把40改成40.0f
rMat = glm::rotate(glm::mat4(1.f), ((glm::radians(40)) * tf), glm::vec3(1.f, 0.f, 0.f));
运行效果
代码
#include "glew/glew.h"#include "glfw/glfw3.h"#include "glm/glm.hpp"#include "glm/gtc/matrix_transform.hpp"#include "glm/gtc/type_ptr.hpp"#include "Utils.h"#include #include #include using namespace std;//#define GLM_FORCE_RADIANSstatic const int Screen_Width = 1920;static const int Screen_Height = 1080;static const int numberVAOs = 1;static const int numberVBOs = 2;GLuint renderingProgram = 0;GLuint vao[numberVAOs] = { 0 };GLuint vbo[numberVBOs] = { 0 };float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;float cubeX = 0.f, cubeY = 0.f, cubeZ = 0.f;int g_width = 0, g_height = 0, g_displayLoopi = 0;float aspect = 0.f;float tf = 0.f;GLuint mvLoc = 0, projLoc = 0;glm::mat4 mMat(1.f), vMat(1.f), mvMat(1.f), projMat(1.f), tMat(1.f), rMat(1.f);void setupVertices(){ float vertexPositions[108] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f }; glGenVertexArrays(numberVAOs, vao); glBindVertexArray(vao[0]); glGenBuffers(numberVBOs, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);}//窗口大小改变时比例位置不变void window_size_callback(GLFWwindow* window, int newWidth, int newHeight){ aspect = (float)newWidth / (float)newHeight; glViewport(0, 0, newWidth, newHeight); //必须要创建透视投影矩阵计算公式,否则第一帧渲染时,立方体不在视口中 :1.0472 radians = 60 degrees //glm::perspective使用模板定义,所以函数各个参数类型要一致 projMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);}void init(GLFWwindow* window){ renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl"); /*GLFW在这里和这里解释文档中的两个坐标系。 简而言之,窗口坐标是相对于监视器和 / 或窗口的,并且以不一定对应于真实屏幕像素的人造单元给出。 当DPI缩放被激活时(例如,在带有视网膜显示器的Mac上),情况尤其如此。 与窗口坐标相比,帧缓冲区的大小与像素相关,以便与glViewport OpenGLs要求相匹配。 请注意,在某些系统上,窗口坐标和像素坐标可以相同,但这不一定是正确的。*/ glfwGetFramebufferSize(window, &g_width, &g_height); aspect = (float)g_width / (float)g_height; //必须要创建透视投影矩阵计算公式,否则第一帧渲染时,立方体不在视口中 :1.0472 radians = 60 degrees //glm::perspective使用模板定义,所以函数各个参数类型要一致 projMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f); cameraX = 0.f; cameraY = 0.f; cameraZ = 16.f; setupVertices();}void display(GLFWwindow* window, float currentTime){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.f, 0.7f, 1.f, 1.f); //启动着色器程序,在GPU上安装GLSL代码,这不会运行着色器程序, glUseProgram(renderingProgram); //获取uniform变量在着色器程序中的位置序号,通过该序号可以设置一致变量的值,如果没有该变量则返回-1 mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix"); projLoc = glGetUniformLocation(renderingProgram, "proj_matrix"); //移动相机矩阵 vMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, cameraZ)); //更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回 // 将透视矩阵和MV 矩阵复制给相应的统一变量 /*通过一致变量(uniform修饰的变量)引用将一致变量值传入渲染管线。 location : uniform的位置。 count : 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。 transpose : 指明矩阵是列优先(column major)矩阵(GL_FALSE)还是行优先(row major)矩阵(GL_TRUE)。 value : 指向由count个元素的数组的指针。 */ glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projMat)); glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat)); for (g_displayLoopi = 0; g_displayLoopi < 36; g_displayLoopi++) { tf = currentTime + g_displayLoopi; //平移矩阵 tMat = glm::translate(glm::mat4(1.f), glm::vec3(glm::sin(.35f * tf) * 8.f, glm::cos(.52f * tf) * 8.f, glm::sin(.70f * tf) * 8.f)); //旋转矩阵,绕x轴旋转 rMat = glm::rotate(glm::mat4(1.f), ((glm::radians(40.f)) * tf), glm::vec3(1.f, 0.f, 0.f)); //旋转矩阵,绕y轴旋转 rMat = glm::rotate(rMat, ((glm::radians(80.f) * tf)), glm::vec3(0.f, 1.f, 0.f)); //旋转矩阵,绕z轴旋转 rMat = glm::rotate(rMat, ((glm::radians(40.f) * tf)), glm::vec3(0.f, 0.f, 1.f)); /*请注意最后一行中的矩阵乘法—— 操作中tMat 和rMat 的顺序很重要。它计算两个变换的结合,平移放在左边,旋转放在右边。 当顶点随后乘以此矩阵时,计算从右到左进行,这意味着首先完成旋转,然后才是平移。 变换的应用顺序很重要,改变顺序会导致不同的行为。图4.7 显示了为立方体设置了动画后 显示的一些帧。*/ mMat = tMat * rMat; //如果mMat和vMat位置变化,将看不到立方体 mvMat = mMat * vMat; //更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回 // 将透视矩阵和MV 矩阵复制给相应的统一变量 glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat)); //glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projMat)); //glBindVertexArray(vao[0]); glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); //指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置 /*Parameters index 指定要修改的顶点属性的索引值 size 指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(梦维:如position是由3个(x, y, z)组成,而颜色是4个(r, g, b, a)) type 指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。 normalized 指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。 stride 指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。 pointer 指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0。 */ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); //开启深度测试 glEnable(GL_DEPTH_TEST); //指定用于深度缓冲比较值; glDepthFunc(GL_LEQUAL); glDrawArrays(GL_TRIANGLES, 0, 36); }}int main(int argc, char** argv){ int glfwStates = glfwInit(); if (glfwStates == GLFW_FALSE) { cout << "GLFW initialize failed, invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << std::endl; glfwTerminate(); exit(EXIT_FAILURE); } /*因为我们要使用OpenGL 4.6,所以我们把GLFW_CONTEXT_VERSION_MAJOR和GLFW_CONTEXT_VERSION_MINOR对应的hint都设置为4和6。 因为我们要使用OpenGL核心模式(这个后面会提到更多),所以我们把GLFW_OPENGL_PROFILE对应的hint设置为GLFW_OPENGL_CORE_PROFILE, 表示使用OpenGL核心模式。最后,把GLFW_RESIZABLE对应的hint设置为GLFW_FALSE,表示窗口不允许用户调整大小。 之所以这样做是因为如果允许用户调整大小,大小发生变化后,窗口的绘制区域默认不变(依然是原来窗口的区域), 也就是说窗口上绘制的图像的大小、位置不会发生改变。为了避免这种现象发生,我们就简单地不让用户调整窗口大小 (当然也有更好的方法,就是用GLFW设置一个窗口大小的回调函数,但这样比较简单)。*/ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE); GLFWwindow* window = glfwCreateWindow(Screen_Width, Screen_Height, "Draw multiple cubes", nullptr, nullptr); if (!window) { cout << "GLFW create window failed, invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << std::endl; glfwTerminate(); exit(EXIT_FAILURE); } /*此函数使调用线程上的指定窗口的 OpenGL 或 OpenGL ES 上下文成为当前上下文。 一次只能在单个线程上使上下文成为当前上下文,并且每个线程一次只能有一个当前上下文。 在线程之间移动上下文时,必须先使其在旧线程上变为非当前状态,然后再在新线程上变为当前状态。 */ glfwMakeContextCurrent(window); //glfwSetFramebufferSizeCallback()和glfwSetWindowSizeCallback区别 glfwSetFramebufferSizeCallback(window, window_size_callback); glfwSetWindowSizeCallback(window, window_size_callback); int glewStates = glewInit(); if (GLEW_OK != glewStates) { cout << "GLEW initialize failed, invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << std::endl; glfwTerminate(); exit(EXIT_FAILURE); } /*此函数设置当前 OpenGL 或 OpenGL ES 上下文的交换间隔,即从调用glfwSwapBuffers开始等待的屏幕更新次数, 然后再交换缓冲区并返回。这有时称为垂直同步、垂直回扫同步或仅vsync。 支持WGL_EXT_swap_control_tear和GLX_EXT_swap_control_tear扩展的上下文也接受负交换间隔,这允许驱动程序立即交换, 即使帧到达有点晚。您可以使用glfwExtensionSupported检查这些扩展。 上下文必须在调用线程上是最新的。在没有当前上下文的情况下调用此函数将导致GLFW_NO_CURRENT_CONTEXT错误。 此功能不适用于 Vulkan。如果您使用 Vulkan 进行渲染,请改为查看交换链的当前模式。 */ glfwSwapInterval(1); init(window); while (!glfwWindowShouldClose(window)) { display(window, (float)glfwGetTime()); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); return 0;}
源码-
源码-
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~