- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
嘿,我很难弄清楚如何为我需要绘制的 3D 杯子创建 360 度底座。我正在使用 GLEW、GLFW 和 GLM 数学
到目前为止,我已经可以创建 3D 立方体和 3D 金字塔了。到目前为止,我的想法是我需要以 360 度的方式创建 6 个或更多的三角形拷贝。我该怎么做?除了创建三角形、立方体、金字塔之外,现代 OpenGL 的资源并不多。
代码:
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
// GLM Mathematics
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
int width, height;
const double PI = 3.14159;
const float toRadians = PI / 180.0f;
// Draw Primitive(s)
void draw()
{
GLenum mode = GL_TRIANGLES;
GLsizei indices = 6;
glDrawElements(mode, indices, GL_UNSIGNED_BYTE, nullptr);
}
// Input Function Prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos);
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
// Declare View Matrix
glm::mat4 viewMatrix;
// Initialize FOV
GLfloat fov = 45.0f;
// Define Camera Attributes
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 target = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraDirection = glm::normalize(cameraPosition - target);
glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight));
glm::vec3 cameraFront = glm::normalize(glm::vec3(0.0f, 0.0f, -1.0f));
// Declare target prototype
glm::vec3 getTarget();
// Camera transformation prototype
void TransformCamera();
// Boolean array for keys and mouse buttons
bool keys[1024], mouseButtons[3];
// Boolean to check camera transformation
bool isPanning = false, isOrbiting = false, isZooming = false;
// Radius, Pitch, and Yaw
GLfloat radius = 3.0f, rawYaw = 0.0f, rawPitch = 0.0f, degYaw, degPitch;
GLfloat deltaTime = 0.0f, lastFrame = 0.0f;
GLfloat lastX = 320, lastY = 240, xChange, yChange;
// Check for any initial mouse movement
bool firstMouseMove = true;
void initCamera();
// Create and Compile Shaders
static GLuint CompileShader(const string& source, GLuint shaderType)
{
// Create Shader object
GLuint shaderID = glCreateShader(shaderType);
const char* src = source.c_str();
// Attach source code to Shader object
glShaderSource(shaderID, 1, &src, nullptr);
// Compile Shader
glCompileShader(shaderID);
// Return ID of Compiled shader
return shaderID;
}
// Create Program Object
static GLuint CreateShaderProgram(const string& vertexShader, const string& fragmentShader)
{
// Compile vertex shader
GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);
// Compile fragment shader
GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// Create program object
GLuint shaderProgram = glCreateProgram();
// Attach vertex and fragment shaders to program object
glAttachShader(shaderProgram, vertexShaderComp);
glAttachShader(shaderProgram, fragmentShaderComp);
// Link shaders to create executable
glLinkProgram(shaderProgram);
// Delete compiled vertex and fragment shaders
glDeleteShader(vertexShaderComp);
glDeleteShader(fragmentShaderComp);
// Return Shader Program
return shaderProgram;
}
int main(void)
{
width = 640; height = 480;
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(width, height, "Main Window", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
// Set input callback functions
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetScrollCallback(window, scroll_callback);
/* Make the window's context current */
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK)
cout << "Error!" << endl;
GLfloat vertices[] = {
// Triangle 1
-0.5, -0.5, 0.0, // index 0
1.0, 0.0, 0.0, // red
-0.5, 0.5, 0.0, // index 1
0.0, 1.0, 0.0, // green
0.5, -0.5, 0.0, // index 2
0.0, 0.0, 1.0, // blue
// Triangle 2
0.5, 0.5, 0.0, // index 3
1.0, 0.0, 1.0 // purple
};
// Define element indices
GLubyte indices[] = {
0, 1, 2,
1, 2, 3
};
// Plane Transforms
glm::vec3 planePositions[] = {
glm::vec3(0.0f, 0.0f, 0.5f),
glm::vec3(0.5f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, -0.5f),
glm::vec3(-0.5f, 0.0f, 0.0f)
};
glm::float32 planeRotations[] = {
0.0f, 90.0f, 0.0f, 90.0f
};
// Setup some OpenGL options
glEnable(GL_DEPTH_TEST);
// Wireframe mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
GLuint VBO, EBO, VAO;
glGenBuffers(1, &VBO); // Create VBO
glGenBuffers(1, &EBO); // Create EBO
glGenVertexArrays(1, &VAO); // Create VOA
glBindVertexArray(VAO);
// VBO and EBO Placed in User-Defined VAO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select VBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Select EBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Load indices
// Specify attribute location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0); // Unbind VOA or close off (Must call VOA explicitly in loop)
// Vertex shader source code
string vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec4 vPosition;"
"layout(location = 1) in vec4 aColor;"
"out vec4 oColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main()\n"
"{\n"
"gl_Position = projection * view * model * vPosition;"
"oColor = aColor;"
"}\n";
// Fragment shader source code
string fragmentShaderSource =
"#version 330 core\n"
"in vec4 oColor;"
"out vec4 fragColor;"
"void main()\n"
"{\n"
"fragColor = oColor;"
"}\n";
// Creating Shader Program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
// Set Delta time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// Resize window and graphics simultaneously
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use Shader Program exe and select VAO before drawing
glUseProgram(shaderProgram); // Call Shader per-frame when updating attributes
// Declare transformations (can be initialized outside loop)
glm::mat4 projectionMatrix;
viewMatrix = glm::lookAt(cameraPosition, getTarget(), worldUp);
projectionMatrix = glm::perspective(fov, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
// Get matrix's uniform location and set matrix
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
//glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glBindVertexArray(VAO); // User-defined VAO must be called before draw.
for (GLuint i = 0; i < 4; i++)
{
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, planePositions[i]);
modelMatrix = glm::rotate(modelMatrix, planeRotations[i] * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
// Draw primitive(s)
draw();
}
// Unbind Shader exe and VOA after drawing per frame
glBindVertexArray(0); //Incase different VAO wii be used after
glUseProgram(0); // Incase different shader will be used after
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
// Poll camera transformations
TransformCamera();
}
//Clear GPU resources
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
// Define Input Callback Functions
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// Display ASCII Keycode
// ALT = ASCII 342
//cout << "ASCII: " << key << endl;
if (action == GLFW_PRESS)
keys[key] = true;
else if (action == GLFW_RELEASE)
keys[key] = false;
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
/*
// Display scroll offset
if (yoffset > 0)
cout << "Scroll Up: ";
if (yoffset < 0)
cout << "Scroll down: ";
cout << yoffset << endl;
*/
/*
if (isZooming)
{
// Clamp FOV
if (fov >= 1.0f && fov <= 55.0f)
fov -= yoffset * 0.01f;
// Default FOV
if (fov < 1.0f)
fov = 1.0f;
if (fov > 45.0f)
fov = 45.0f;
}
*/
}
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
{
// cout << "Mouse X: " << xpos << endl;
// cout << "Mouse Y: " << ypos << endl;
if (firstMouseMove)
{
lastX = xpos;
lastY = ypos;
firstMouseMove = false;
}
// Calculate cursor offset
xChange = xpos - lastX;
yChange = lastY - ypos;
lastX = xpos;
lastY = ypos;
// Zoom Camera
if (isZooming)
{
if (fov < 1.0f)
fov = 1.0f;
if (fov > 45.0f)
fov = 45.0f;
if (xpos > 0)
fov -= lastX * 0.01f;
if (ypos > 0)
fov -= lastY * 0.01f;
}
// Pan camera
if (isPanning)
{
if (cameraPosition.z > 0.f)
cameraFront.z = 1.0f;
else
cameraFront.z = -1.0f;
GLfloat cameraSpeed = xChange * deltaTime;
cameraPosition += cameraSpeed * cameraRight;
cameraSpeed = yChange * deltaTime;
cameraPosition += cameraSpeed * cameraUp;
}
// Orbit camera
if (isOrbiting)
{
rawYaw += xChange;
rawPitch += yChange;
// Convert Yaw and Pitch to degrees
degYaw = glm::radians(rawYaw);
// degPitch = glm::radians(rawPitch);
degPitch = glm::clamp(glm::radians(rawPitch), -glm::pi<float>() / 2.0f + .1f, glm::pi<float>() / 2.0f - .1f);
// Azimuth Altitude Formula
cameraPosition.x = target.x + radius * cosf(degPitch) * sinf(degYaw);
cameraPosition.y = target.y + radius * sinf(degPitch);
cameraPosition.z = target.z + radius * cosf(degPitch) * cosf(degYaw);
}
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
/*
// Detect Mouse Button Clicks
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
cout << "LMB Clicked" << endl;
if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS)
cout << "MMB Clicked" << endl;
if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
cout << "RMB Clicked" << endl;
*/
if (action == GLFW_PRESS)
mouseButtons[button] = true;
else if (action == GLFW_RELEASE)
mouseButtons[button] = false;
}
// Define getTarget function
glm::vec3 getTarget()
{
if (isPanning)
target = cameraPosition + cameraFront;
return target;
}
// Define TransformCamera function
void TransformCamera()
{
// Pan camera if left alt key and middle mouse button pressed same time
if (keys[GLFW_KEY_LEFT_ALT] && mouseButtons[GLFW_MOUSE_BUTTON_MIDDLE])
isPanning = true;
else
isPanning = false;
// Orbit camera if left alt key and left mouse button pressed same time
if (keys[GLFW_KEY_LEFT_ALT] && mouseButtons[GLFW_MOUSE_BUTTON_LEFT])
isOrbiting = true;
else
isOrbiting = false;
// Zoom camera if left alt key and right mouse button pressed same time
if (keys[GLFW_KEY_LEFT_ALT] && mouseButtons[GLFW_MOUSE_BUTTON_RIGHT])
isZooming = true;
else
isZooming = false;
// Reset Camera
if (keys[GLFW_KEY_F])
initCamera();
}
void initCamera()
{
cameraPosition = glm::vec3(0.0f, 0.0f, 3.0f);
target = glm::vec3(0.0f, 0.0f, 0.0f);
cameraDirection = glm::normalize(cameraPosition - target);
worldUp = glm::vec3(0.0f, 1.0f, 0.0f);
cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));
cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight));
cameraFront = glm::normalize(glm::vec3(0.0f, 0.0f, -1.0f));
}
最佳答案
关于c++ - 为 3D 杯子创建圆柱体底座(现代 OpenGL、GLM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59130804/
我有一个库(围绕nlohmann / json封装),可以从JSON反序列化: struct MyStruct { int propertyA; std::string propert
如果 的第 1、3、5、7、9、11、13 或 15 位之一,我希望 var 不等于 FALSE输入已设置。 一个似乎相当普遍的解决方案是: int var = 1 & (input >> 1) |
当我说目标类型时,我的意思是使用接收者变量或参数的类型作为信息来推断我分配给它的部分代码。例如,在 C# 中,您会编写类似这样的内容来传递可为 null 的值或 null (空)如有必要: void
我需要从 native 内存读取/写入一堆结构。我想弄清楚我是否应该为结构对齐而烦恼。这是我编写的用于测试的简单代码。它将压缩结构写入未对齐的指针,然后读回该结构: public static uns
采用以下代码: char chars[4] = {0x5B, 0x5B, 0x5B, 0x5B}; int* b = (int*) &chars[0]; (int*) &chars[0] 值将在循环(
因此,当我发现将整个解决问题的方法颠倒过来时,我正在网上搜索最佳实践,以实现使用多个数据存储的存储库模式。这就是我所拥有的... 我的应用程序是一个BI工具,它从四个数据库中提取数据。由于内部限制,我
我想仅使用现代 OpenGL 技术(即没有即时模式的东西)来设置正交投影。我在网络上看到有关如何处理此问题的相互矛盾的信息。 有些人说调用 glMatrixMode(GL_PROJECTION) 然后
我想知道当前的 cpus 是否避免在其中至少一个为零时将两个数字相乘。谢谢 最佳答案 这取决于 CPU 和(在某些情况下)操作数的类型。 较旧/较简单的 CPU 通常使用如下乘法算法: integer
在精美的 OpenGL 新版本(3.0 和 4.0 以上)中,不推荐使用 gl_Vertex 等内置顶点属性 .实际渲染任何东西的“新方法”是为位置、颜色等指定您自己的顶点属性,然后将这些自定义属性绑
在我的 OpenGL 研究(我认为是 OpenGL 红皮书)中,我遇到了一个关节机器人 ARM 模型的示例,该模型由“上臂”、“下臂”、“手”和五个或更多“手指”。每个部分都应该能够独立移动,但受“关
像 Kaby Lake 这样的现代 CPU 如何处理小分支? (在下面的代码中,它是跳转到标签 LBB1_67)。据我所知,分支不会有害,因为跳转低于 16 字节块大小,即解码窗口的大小。 或者是否有
编辑:此问题假设您启用了发生检查。不是关于 setting Prolog flags . 30 年前有很多关于在安全的情况下自动优化发生检查的论文(大约 90% 的谓词,在典型的代码库中)。提出了不同
现在是 2020 年,在 iOS 终于添加了对 Widget 的支持之后,Widget 再次风靡一时。但是,自 2012 年以来,Android 小部件似乎没有更新。 来自 Android docs
我正在看一些关于算法的讲座,教授用乘法作为如何改进朴素算法的例子...... 它让我意识到乘法并不是那么明显,虽然当我编码时我只是认为它是一个简单的原子操作,乘法需要一个算法来运行,它不像求和数字那样
我们将 PIXI.js 用于内部使用 WebGL 进行渲染的游戏。时不时地,我会偶然发现避免 NPOT 纹理(https://developer.mozilla.org/en-US/docs/Web/
我是一名计算机科学专业的学生,即将毕业。我们现在必须用我们选择的语言编写完整的应用程序。我们选择 Objective-C 因为我们都是 Mac 人。 为了让我们的教授高兴,必须做一些事情:-)一项
我正在编写一个带有 x86 后端的 JIT 编译器,并且正在学习 x86 汇编器和机器代码。大约 20 年前,我使用 ARM 汇编程序,并对这些架构之间的成本模型差异感到惊讶。 具体来说,内存访问和分
如果负载与两个较早的存储重叠(并且负载未完全包含在最旧的存储中),现代 Intel 或 AMD x86 实现能否从两个存储转发以满足负载? 例如,考虑以下序列: mov [rdx + 0], eax
http://www.lighthouse3d.com/opengl/glsl/index.php?ogldir2 报告 OpenGL 上下文中的半向量是“眼睛位置 - 灯光位置”,但接着又说“幸运的
在现代 (GL3.3+) GPU 上使用 GLSL 时,在统一上进行分支的可能成本是多少? 在我的引擎中,我已经达到了拥有大量着色器的程度。我为其中的很多预设了几种不同的质量预设。就目前情况而言,我在
我是一名优秀的程序员,十分优秀!