如何在不使用glm头文件情况下实现
时间: 2024-11-15 18:32:25 浏览: 0
如果你不想使用`glm`库来处理向量和矩阵操作,你可以手动编写一些基本的数学函数来完成坐标转换。不过这会比较繁琐,因为OpenGL的矩阵运算涉及旋转、缩放和平移等复杂操作。以下是使用原生C++和基本数学函数实现正投影的一个简化版本:
```cpp
#include <vector>
#include <iostream>
// 二维向量
struct Vector2 {
float x, y;
// 加法和乘法
Vector2 operator+(const Vector2& other) const { return {x + other.x, y + other.y}; }
Vector2 operator*(float scalar) const { return {x * scalar, y * scalar}; }
// 根据距离调整比例
void adjustScale(float minDistance, float maxDistance) {
float scale = (maxDistance - minDistance) / std::abs(x);
if (scale > 1)
scale = 1; // 防止放大过头
x = scale;
y = scale;
}
};
// 定义正投影
void orthographicProjection(const Vector2& viewPosition, const float left, const float right, const float bottom, const float top) {
const float width = right - left;
const float height = top - bottom;
// 创建投影矩阵
float proj[4][4] = {
{2.0f / width, 0, 0, -(right + left) / width},
{0, 2.0f / height, 0, -(top + bottom) / height},
{0, 0, 0, 1},
{0, 0, 0, 0} // 将最后一行设置为透视部分,这里为了简化为平行投影
};
// 转换到OpenGL的列向量形式
float* projCol = new float[16];
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
projCol[i * 4 + j] = proj[j][i];
// 将变换应用到当前的视口
glMatrixMode(GL_PROJECTION);
glLoadTransposeMatrixf(projCol);
delete[] projCol;
}
// 示例中的正方体顶点和索引
std::vector<Vector2> vertices = ...;
unsigned int indices[] = ...;
// 渲染函数
void drawCube(Vector2 origin, float side) {
// 省略了创建VBO和IBO的步骤
glPushMatrix();
glTranslatef(origin.x, origin.y, 0); // 移动到视口位置
for (auto& vertex : vertices) {
vertex.adjustScale(side, side); // 根据需要调整每个顶点的比例
glVertex2f(vertex.x, vertex.y); // 绘制顶点
}
glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(unsigned int), GL_UNSIGNED_INT, (GLvoid*)0);
glPopMatrix(); // 恢复原始变换
}
int main() {
// 设置视口和正投影
Vector2 viewportPosition = {0, 0};
orthographicProjection(viewportPosition, -1, 1, -1, 1);
// 初始化并绘制正方体
// ...
return 0;
}
```
这个例子中,我们自己实现了二维向量的加减法,并使用`adjustScale`函数来根据正投影的范围调整顶点的x和y值。注意,这个方法没有包括深度信息,所以效果可能会略有不同。
阅读全文