Camera::Camera(vec3 u, vec3 loc, vec3 la, float a, int width, int height): angle(a){ up = u; location = loc; lookat = la; camz = vec3_norm(vec3_sub(lookat, location)); camx = vec3_norm(vec3_mul_cross(up, camz)); camy = vec3_mul_cross(camx, vec3_sub((vec3) {0., 0., 0.}, camz)); camy = vec3_norm(camy); tax = tan(angle); tay = tan(((float) height / (float) width) * angle); }
static inline void _setup_camera(game *g) { if (g->d.ortho) { mat4x4_ortho(g->d.proj, -g->aspect, g->aspect, -1, 1, 0.001, 1000); } else { mat4x4_perspective(g->d.proj, 45.0, g->aspect, 0.001, 1000.0); } vec3_sub(g->d.view_f, g->d.center, g->d.eye); vec3_norm(g->d.view_f, g->d.view_f); vec3_mul_cross(g->d.view_r, g->d.view_f, g->d.up); vec3_norm(g->d.view_r, g->d.view_r); vec3_mul_cross(g->d.view_u, g->d.view_r, g->d.view_f); _calc_zoom(g, 0); // Update zoom for this view type }
void V_CreateHeightMap(model_t* m, sprite* s, double size, double height) { int w = s->w, h = s->h; if (w < 1 || h < 1) SYS_Error("Heightmap has an invalid width or height. "); int vertCount = w * h; int indexCount = (w - 1) * (h - 1) * 6; memset(m, 0, sizeof(model_t)); for (int i = 0; i < m->boneCount; i++) m->bones[i].keyCount = 0; VAO_t* vao = &m->vao; glGenVertexArrays(1, &vao->id); glBindVertexArray(vao->id); vao->vertCount = vertCount; vao->indexCount = indexCount; vao->vert.bufferSize = 3 * vertCount * sizeof(float); vao->vert.buffer = malloc(vao->vert.bufferSize); double hScale = size / w, vScale = size / h; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { double sampleHeight = ((s->pix[y * w + x] & 0xFF000000) >> 24) / 256.0; ((float*)vao->vert.buffer)[y * w * 3 + x * 3 + 0] = x * hScale; ((float*)vao->vert.buffer)[y * w * 3 + x * 3 + 1] = sampleHeight * height; ((float*)vao->vert.buffer)[y * w * 3 + x * 3 + 2] = y * vScale; } } V_InitVBO(&vao->vert, 0, 3, GL_FLOAT); vao->uv.bufferSize = 3 * vertCount * sizeof(float); vao->uv.buffer = malloc(vao->uv.bufferSize); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { ((float*)vao->uv.buffer)[y * w * 3 + x * 3 + 0] = x; ((float*)vao->uv.buffer)[y * w * 3 + x * 3 + 1] = y; ((float*)vao->uv.buffer)[y * w * 3 + x * 3 + 2] = 0; } } V_InitVBO(&vao->uv, 1, 3, GL_FLOAT); vao->normal.bufferSize = 3 * vertCount * sizeof(float); vao->normal.buffer = malloc(vao->normal.bufferSize); for (int i = 0; i < vertCount; i++) { vec3 normal = {0, 0, 0}; int x = i % w, y = i / w; int xMin = x == 0 ? x : x - 1; int xMax = x >= w - 1 ? x : x + 1; float yDelta = ((float*)vao->vert.buffer)[y * w * 3 + xMax * 3 + 1] - ((float*)vao->vert.buffer)[y * w * 3 + xMin * 3 + 1]; float xDelta = xMax - xMin; float zAngle = atan2(yDelta, xDelta); normal[1] = cos(zAngle); int yMin = y == 0 ? y : y - 1; int yMax = y >= h - 1 ? y : y + 1; yDelta = ((float*)vao->vert.buffer)[yMax * w * 3 + x * 3 + 1] - ((float*)vao->vert.buffer)[yMin * w * 3 + x * 3 + 1]; float zDelta = yMax - yMin; float xAngle = atan2(yDelta, zDelta); normal[1] *= cos(xAngle); normal[0] = -sin(zAngle); normal[2] = -sin(xAngle); ((float*)vao->normal.buffer)[i * 3 + 0] = normal[0]; ((float*)vao->normal.buffer)[i * 3 + 1] = normal[1]; ((float*)vao->normal.buffer)[i * 3 + 2] = normal[2]; } V_InitVBO(&vao->normal, 2, 3, GL_FLOAT); vao->tangents.bufferSize = 3 * vertCount * sizeof(float); vao->tangents.buffer = malloc(vao->tangents.bufferSize); for (int i = 0; i < vertCount; i++) { vec3_mul_cross(&((float*)vao->tangents.buffer)[i * 3], &((float*)vao->normal.buffer)[i * 3], (vec3) {0, 0, 1}); } V_InitVBO(&vao->tangents, 4, 3, GL_FLOAT); glGenBuffers(1, &vao->index.id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->index.id); vao->index.type = GL_UNSIGNED_INT; vao->index.dim = 1; vao->index.buffer = malloc(indexCount * sizeof(int)); for (int x = 0; x < w - 1; x++) { for (int y = 0; y < h - 1; y++) { ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 0] = y * w + x; ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 1] = (y + 1) * w + x; ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 2] = y * w + x + 1; ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 3] = (y + 1) * w + x; ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 4] = (y + 1) * w + x + 1; ((int*)vao->index.buffer)[y * (w - 1) * 6 + x * 6 + 5] = y * w + x + 1; } } glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(int), vao->index.buffer, GL_STATIC_DRAW); vao->weights.buffer = NULL; }