#define GL_GLEXT_PROTOTYPES
#define _USE_MATH_DEFINES
#include <uthash.h>
#if defined(_WIN32)
#if defined(__GNUC__)
#include <cpuid.h>
#elif defined(_MSC_VER)
#include <intrin.h>
#endif
//#define APIENTRY __stdcall
#include <windows.h>
#include <errno.h>
#define GLEW_STATIC
#include <GL/glew.h>
//#include "glew/glew.h"
//#include <GL/gl.h>
//#include <GLES2/gl2.h>
//#include <GLES2/gl2ext.h>
//#define GLFW_INCLUDE_ES3
#define GLFW_EXPOSE_NATIVE_WGL
#define GLFW_EXPOSE_NATIVE_WIN32
#else
#include <GL/gl.h>
//#include <GL/glext.h>
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
//#define STB_IMAGE_IMPLEMENTATION
//#include "stb_image.h"
//#include "lodepng.h" // alternative to stb_image, may be slower
//#define STB_IMAGE_WRITE_IMPLEMENTATION
//#include "stb_image_write.h" //Just for test purposes
#include "linmathv2.h"
#include "geometry.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0)
#define radToDeg(angleInRadians) ((angleInRadians) * 180.0 / M_PI)
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower)))
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "custom.h" // early declarations
#include "input.h" // input glfw callbacks/mouse
#include "shaders.h" // shader code texts
#include "water.h" //
#include "terrain.h" //
#include "sky.h" // sky for sun/moonpos
//#include "text.h" // all related text/glyph/font
#define nullptr ((void*)0)
#define vstr(s) str(s)
#define str(s) #s
// start terrain collider
float get_terrain_height(float x, float z, int width, int height, float grid_size) {
// Step 2: Grid indices
int i = (int)(x / grid_size);
int j = (int)(z / grid_size);
if (i < 0 || i >= width-1 || j < 0 || j >= height-1) return 0.0f; // Boundary handjling
i=(int)z;
j=(int)x;
// Step 3: Fractional coordinates
//float x0 = i * grid_size;
//float z0 = j * grid_size;
float x0 = i;
float z0 = j;
float fx = (x - x0) / grid_size;
float fz = (z - z0) / grid_size;
// Step 4-6: Triangle selection and barycentric coordinates
Vec3 v0, v1, v2;
float a, b, c;
if (fz <= 1.0f - fx) { // Triangle 1
v0 = (Vec3){x0, terrainCollider[i * height + j], z0};
v1 = (Vec3){x0 + grid_size, terrainCollider[(i+1) * height + j], z0};
v2 = (Vec3){x0, terrainCollider[i * height + j+1], z0 + grid_size};
a = 1.0f - fx - fz;
b = fx;
c = fz;
} else { // Triangle 2
v0 = (Vec3){x0 + grid_size, terrainCollider[(i+1) * height + j], z0};
v1 = (Vec3){x0 + grid_size, terrainCollider[(i+1) * height + j+1], z0 + grid_size};
v2 = (Vec3){x0, terrainCollider[i * height + j+1], z0 + grid_size};
a = 1.0f - fx;
b = fx + fz - 1.0f;
c = 1.0f - fz;
}
//printf("x:%f, z:%f, x0:%f, z0:%f, fx=%f, fz=%f, a:%f\n",x,z,x0,z0,fx,fz,a);
// Step 7: Interpolate height
return a * v0.y + b * v1.y + c * v2.y;
}
int check_collision(float x, float y, float z, int width, int height, float grid_size, float *retHeight) {
float y_terrain = get_terrain_height(x, z, width, height, grid_size);
int collided=y<=y_terrain;
//printf("collided:%d, height:%f\n",collided,y_terrain);
*retHeight=y_terrain;
return collided;
//return y <= y_terrain; // 1 if collision, 0 if above
}
// end terrain collider
// start box collider
typedef struct {
float min_x, min_y, min_z;
float max_x, max_y, max_z;
} AABB;
int aabb_collide(AABB a, AABB b) {
return (a.min_x < b.max_x && a.max_x > b.min_x) &&
(a.min_y < b.max_y && a.max_y > b.min_y) &&
(a.min_z < b.max_z && a.max_z > b.min_z);
}
// Function to check collision and get the normal
int aabb_normal(AABB player, AABB block, float* normal_x, float* normal_y, float* normal_z) {
float overlap_x = fmin(player.max_x, block.max_x) - fmax(player.min_x, block.min_x);
float overlap_y = fmin(player.max_y, block.max_y) - fmax(player.min_y, block.min_y);
float overlap_z = fmin(player.max_z, block.max_z) - fmax(player.min_z, block.min_z);
float epsilon = 1.0;
if(player.min_y - block.max_y < epsilon) {
*normal_y = (player.min_y < block.min_y) ? 1.0f : -1.0f;
*normal_x = 0.0f;
*normal_z = 0.0f;
return 1; // Collision detected
} else {
if (overlap_x > 0 && overlap_y > 0 && overlap_z > 0) {
// Collision occurred, find smallest overlap
if (overlap_x < overlap_y && overlap_x < overlap_z) {
*normal_x = (player.min_x < block.min_x) ? 1.0f : -1.0f;
*normal_y = 0.0f;
*normal_z = 0.0f;
} else if (overlap_y < overlap_z) {
*normal_y = (player.min_y < block.min_y) ? 1.0f : -1.0f;
*normal_x = 0.0f;
*normal_z = 0.0f;
} else {
*normal_z = (player.min_z < block.min_z) ? 1.0f : -1.0f;
*normal_x = 0.0f;
*normal_y = 0.0f;
}
return 1; // Collision detected
}
return 0; // No collision
}
return 0;
}
int initStairs=0;
float *block_colliders;
int stairSteps=25;
int checkBlockColliders(AABB player_aabb, float *rh) {
if(initStairs!=1) return 1;
float dist=0.0f;
Vec3 *p1=malloc(sizeof(Vec3));
Vec3 *p2=malloc(sizeof(Vec3));
int collide=0;
for(int i=0;i<stairSteps;++i) {
p1->x=block_colliders[i*6];
p1->y=block_colliders[i*6+1];
p1->z=block_colliders[i*6+2];
p2->x=player->transform->position->x;
p2->y=player->transform->position->y;
p2->z=player->transform->position->z;
//dist=vector3_distance(p1,p2);
dist=calculate_distance(p1,p2); // correct measure return
//printf("dist block %d = %f\n",i,dist);
if(dist<block_colliders[i*6+5]) { // or +3 should be equal
//within radius of longest point, check intersections
// AABB ?
float minx=block_colliders[i*6]-(block_colliders[i*6+3]);
float miny=block_colliders[i*6+1]-(block_colliders[i*6+4]);
float minz=block_colliders[i*6+2]-(block_colliders[i*6+5]);
float maxx=block_colliders[i*6]+(block_colliders[i*6+3]);
float maxy=block_colliders[i*6+1]+(block_colliders[i*6+4]);
float maxz=block_colliders[i*6+2]+(block_colliders[i*6+5]);
//printf("within range of block %d, dist=%f\n",i,dist);
AABB block_aabb = {minx, miny, minz,
maxx, maxy, maxz};
if (aabb_collide(player_aabb, block_aabb)) {
//player.min_y - ground.max_y < epsilon
float nx, ny, nz;
if (aabb_normal(player_aabb, block_aabb, &nx, &ny, &nz)) {
//printf("nx: %f, ny: %f, nz: %f\n",nx,ny,nz);
if (ny != 0) { // Normal points up, surface is below
//printf("Player is on the ground!\n");
// Set ground state to true
*rh=block_colliders[i*6+1]+block_colliders[i*6+4];
collide=2;
break;
}
}
collide=1;
break;
}
}
}
free(p1);
free(p2);
return collide;
}
// end box collider
float speed = 4.0f;
float strifeSpeed = 4.0f;
float rotSpeed = 120.0f*1.0f; // deg per sec
float speedMulti = 1.0f;
float addSpeed = 0.0f;
float velocityY=0.0f; // up/down
float velocityX=0.0f; // sides // not in use yet
float velocityZ=0.0f; // forward/back // not in use yet
bool isGrounded = false;
float gravityCalc = 9.53f; // 9.53?
float isJumping = 0.0f;
int isSwimming = 0;
int moveMode = 0; // 0 = free mode, 1 = player mode
int applyXoffset = 0;
bool readyXoffset = false;
bool swapStrife = true;
void handle_move() { // fixed movement ticks
velocityX=0;
velocityY=0;
velocityZ=0;
float last_x = player->transform->position->x;
float last_y = player->transform->position->y;
float last_z = player->transform->position->z;
AABB player_aabb = {last_x - 0.5f, last_y - 1.0f, last_z - 0.5f,
last_x + 0.5f, last_y + 1.0f, last_z + 0.5f};
if(LMB_press && RMB_press) is_moving=1; // others in input.c
if(moveMode == 1) { // player mode
if(isJumping<=0.0f) {
if(is_moving==1) { // W | ArrowUp
is_moving=0;
// forward relative to world xz
// rotation player equal camera direction forward
velocityX += -player->transform->rotation->x * speed * speedMulti;
velocityY += -player->transform->rotation->y * speed * speedMulti;
velocityZ += -player->transform->rotation->z * speed * speedMulti;
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
} else if(is_moving==-1) { // S | ArrowDown
is_moving=0;
velocityX += player->transform->rotation->x * speed * speedMulti;
velocityY += player->transform->rotation->y * speed * speedMulti;
velocityZ += player->transform->rotation->z * speed * speedMulti;
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
}
}
} else if(moveMode == 0) { // free mode
if(addSpeed>0.0f) {
//addSpeed -= updateDeltaTime;
--addSpeed;
velocityX += -camera->dir->forward->x * addSpeed * speedMulti;
velocityY += -camera->dir->forward->y * addSpeed * speedMulti;
velocityZ += -camera->dir->forward->z * addSpeed * speedMulti;
}
if(readyBlink) {
addSpeed = 50.0f;
//addSpeed += 3.0f;
//addSpeed=CLAMP(addSpeed,255.0f,0.0f);
readyBlink=false;
}
if(is_moving==1) { // W | ArrowUp
is_moving=0;
// forward relative to camera look
velocityX += -camera->dir->forward->x * speed * speedMulti;
velocityY += -camera->dir->forward->y * speed * speedMulti;
velocityZ += -camera->dir->forward->z * speed * speedMulti;
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
} else if(is_moving==-1) { // S | ArrowDown
is_moving=0;
if(addSpeed>0.0f) {
addSpeed -= 2.0f; // break
}
velocityX += camera->dir->forward->x * speed * speedMulti;
velocityY += camera->dir->forward->y * speed * speedMulti;
velocityZ += camera->dir->forward->z * speed * speedMulti;
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
//} else if(addSpeed>0.0f) {
// addSpeed -= 2.0f; // break
}
}
// Jumping / Flying / swimming
if(moveMode == 1) { // player mode swim fall gravity
float waterDiff=player->transform->position->y-waterHeightSample;
float heightChange=waterHeightSample-lastWaterHeightSample;
lastWaterHeightSample=waterHeightSample;
//printf("waterDiff = %f, waterHeightSample = %f, playerY = %f\n",waterDiff,waterHeightSample,player->transform->position->y);
//printf("isSwim: %d, isJump: %f, isGround: %d\n",isSwimming,isJumping,isGrounded);
if(waterDiff<0.0f) {
if((isSwimming==0 || isSwimming==2) && isJumping<=0.0f) {
isSwimming = 1;
}
}
if(isSwimming>0) {
if(isJumping>0.0f) { // still going up
velocityY += (gravityCalc)*1.2; // upward
isJumping-=fixedDeltaTime;
} else {
if(waterDiff >= -0.5f && waterDiff <= 1.0f) {
// follow water up/down
player->transform->position->y+=heightChange;
}
if(waterDiff>0.0f && isJumping<=0.0f) {
velocityY += -gravityCalc*3; // fall
//printf("swim falling\n");
} else {
if(is_elevating==1) {
is_elevating = 0;
if(isSwimming!=2) {
velocityY += 1.0f * speed * speedMulti;
if(isJumping<=0.0f) {
//printf("swim jump\n");
isJumping=0.2f;
}
isSwimming = 2;
}
} else if(is_elevating==-1) {
is_elevating = 0;
velocityY += -1.0f * speed * speedMulti;
}
}
}
} else {
if(isJumping>0.0f) { // still going up
velocityY += (gravityCalc)*1.2; // upward
isJumping-=fixedDeltaTime;
} else {
if(!isGrounded) { // falling
velocityY += -gravityCalc*3;
} else if(is_elevating==1) {
if(isJumping<=0.0f && isGrounded) {
isJumping=0.2f;
isGrounded=false;
is_elevating=0;
}
} else {
isJumping=0.0f;
}
}
float fullFall=1.0/fixedDeltaTime;
velocityY=CLAMP(velocityY,gravityCalc*fullFall,-gravityCalc*fullFall); // fall,jump
}
} else if(moveMode == 0) { // free mode
if(is_elevating==1) {
is_elevating = 0;
velocityY += 1.0f * speed * speedMulti;
} else if(is_elevating==-1) {
is_elevating = 0;
velocityY += -1.0f * speed * speedMulti;
}
}
// Turning/Strifing
if(is_turning!=0) { // all modes
bool applyStrife = false;
if(is_turning==1) { // A | ArrowLeft
if((mouse_drag_started || shiftDown) && (RMB_press || moveMode==0)) {
applyStrife = true;
} else {
if(mouse_drag_started && !RMB_press) {
// lock camera but keep rotating player
camera->xOffset -= rotSpeed * fixedDeltaTime;
} else {
camera->theta -= rotSpeed * fixedDeltaTime;
}
}
if(applyStrife) {
if(moveMode == 1 || shiftDown) swapStrife = false;
if(swapStrife && !mouse_drag_started) {
velocityX += -player->dir->right->x * strifeSpeed * speedMulti;
velocityZ += -player->dir->right->z * strifeSpeed * speedMulti;
} else {
velocityX += player->dir->right->x * strifeSpeed * speedMulti;
velocityZ += player->dir->right->z * strifeSpeed * speedMulti;
}
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
}
is_turning=0;
} else if(is_turning==-1) { // D | ArrowLeft
if((mouse_drag_started || shiftDown) && (RMB_press || moveMode==0)) {
applyStrife = true;
} else {
if(mouse_drag_started && !RMB_press) {
// lock camera but keep rotating player
camera->xOffset += rotSpeed * fixedDeltaTime;
} else {
camera->theta += rotSpeed * fixedDeltaTime;
}
}
if(applyStrife) {
if(moveMode == 1 || shiftDown) swapStrife = false;
if(swapStrife && !mouse_drag_started) {
velocityX += player->dir->right->x * strifeSpeed * speedMulti;
velocityZ += player->dir->right->z * strifeSpeed * speedMulti;
} else {
velocityX += -player->dir->right->x * strifeSpeed * speedMulti;
velocityZ += -player->dir->right->z * strifeSpeed * speedMulti;
}
if(!mouse_drag_started) {
readyXoffset=true;
applyXoffset=1; // camera to player
}
}
is_turning=0;
}
}
// Mouse actions / drag / rotate / colliders
if(moveMode == 0) { // free mode
if(mouse_drag_started) { // MouseLMB=MouseRMB
bool dragXZ=false;
bool dragY=false;
float RMBstrifeS = x_input * 10.0f * fixedDeltaTime;
float RMBstrifeU = y_input * 10.0f * fixedDeltaTime;
// left/right
if(RMB_press && is_moving==0) { // Mouse Move
if(!shiftDown) { // up/down
dragXZ=true;
} else { // forward/back
dragY=true;
}
readyXoffset=true;
applyXoffset=2; // player to camera
is_turning=0;
} else { // Mouse Rotate/orient set
//if(!shiftDown) { // up/down
camera->phi -= y_input * 5.0f * fixedDeltaTime;
camera->theta += x_input * 5.0f * fixedDeltaTime;
//} else {
// dragXZ=true;
//}
readyXoffset=true;
applyXoffset=2; // player to camera in free mode, not to be confused with future but non existent 'fly' mode
}
if(dragXZ) {
velocityX += camera->dir->right->x * RMBstrifeS * speedMulti;
velocityY += camera->dir->right->y * RMBstrifeS * speedMulti;
velocityZ += camera->dir->right->z * RMBstrifeS * speedMulti;
velocityX += camera->dir->up->x * RMBstrifeU * speedMulti;
velocityY += camera->dir->up->y * RMBstrifeU * speedMulti;
velocityZ += camera->dir->up->z * RMBstrifeU * speedMulti;
} else if(dragY) {
velocityX += camera->dir->forward->x * RMBstrifeU * speedMulti;
velocityY += camera->dir->forward->y * RMBstrifeU * speedMulti;
velocityZ += camera->dir->forward->z * RMBstrifeU * speedMulti;
}
}
} else if(moveMode == 1) { // player mode
if(mouse_drag_started) { // MouseLMB=MouseRMB
if(RMB_press && is_moving==0) { // Mouse Move
// line player to camera first here
camera->phi -= y_input * 5.0f * fixedDeltaTime;
camera->theta += x_input * 5.0f * fixedDeltaTime;
player->phi -= y_input * 5.0f * fixedDeltaTime;
readyXoffset=true;
applyXoffset=2; // player to camera
is_turning=0;
} else { // Mouse Rotate/orient set
camera->phi -= y_input * 5.0f * fixedDeltaTime;
camera->theta += x_input * 5.0f * fixedDeltaTime;
camera->xOffset -= x_input * 5.0f * fixedDeltaTime; // separate alignment from player
readyXoffset=true;
}
}
}
// apply velocity
player->transform->position->x += velocityX * fixedDeltaTime;
player->transform->position->y += velocityY * fixedDeltaTime;
player->transform->position->z += velocityZ * fixedDeltaTime;
float cO=cubeScale*2;
// Update player AABB after movement
player_aabb.min_x = player->transform->position->x - cO; player_aabb.max_x = player->transform->position->x + cO;
player_aabb.min_y = player->transform->position->y - cO; player_aabb.max_y = player->transform->position->y + cO;
player_aabb.min_z = player->transform->position->z - cO; player_aabb.max_z = player->transform->position->z + cO;
//printf("velocityX=%f, velocityY=%f, velocityZ=%f, isGrounded=%d, isJumping:%f\n",velocityX,velocityY,velocityZ,isGrounded,isJumping);
// Check collisions
if(moveMode == 1) { // player mode
float retHeight=0;
int bcollided=checkBlockColliders(player_aabb,(void *)&retHeight);
if(bcollided==1) {
player->transform->position->x=last_x;
player->transform->position->y=last_y;
player->transform->position->z=last_z;
} else if(bcollided==2) {
isGrounded=true; // block ground
if(player->transform->position->y<retHeight+cO) {
player->transform->position->y=retHeight+cO;
}
}
if(bcollided!=2) {
//terrain collider
float halfBlock = terrainScale/2; // 2f alignment fix
if(check_collision(
((player->transform->position->x+halfBlock)/terrainScale)-gridLeft,
player->transform->position->y-cO,
((player->transform->position->z+halfBlock)/terrainScale)-gridTop
, gridWidth, gridHeight, gridHeight,&retHeight)==1) {
isGrounded=true;
if(isSwimming>0) {
isSwimming=0;
}
} else {
isGrounded=false;
}
if(retHeight!=0) {
if(player->transform->position->y<retHeight+cO) {
player->transform->position->y=retHeight+cO;
}
}
}
}
x_input = 0.0f;
y_input = 0.0f;
//printf("player offset x:%f, z:%f\n",player->transform->position->x-gridLeft,player->transform->position->z-gridTop);
}
int RenderSpinningQuad() {
// draw main rotating quad in mbp
glUseProgram(0);
glUseProgram(program);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
setRenderModePerspective();
//Vec3 dir = {
// player->transform->rotation->x,
// 0,
// //player->transform->rotation->y,
// player->transform->rotation->z,
//};
//Quaternion q = directionToQuaternion(dir);
//Vec3 rot={0.0f, glfwGetTime(), 0.0f};
//Quaternion q = ToQuaternion(rot);
//mat4x4 RotationMatrix;
//QuaternionToMat4(RotationMatrix,&q);
//mat4x4_mul(m, m, RotationMatrix);
mat4x4 vc;
memcpy(vc,v,sizeof(vc));
mat4x4_rotate_Z(vc, vc, (float) glfwGetTime());
applyScalingToModel(m, 1.43,1.0f,1.0f);
execRenderModePerspective(vc);
setUniform4m(&program, "MVP", mvp);
setUniform1i(&program, "texture1", 0);
setUniform1i(&program, "mix", 1);
glBindTexture(GL_TEXTURE_2D, texture1);
glBindVertexArray(plane_array);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//printf("about to fail 2\n");
glBindVertexArray(0);
RenderBoundBox(-0.66f,0.5f,0.0f,0.66*2,1.0f,0.0f,1,mvp);
return 0;
}
int RenderCube() {
glUseProgram(0);
glUseProgram(programCube);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
//setUniform1i(&programCube, "texture1", 0);
//
setRenderModePerspective();
// transate position in view matrix (v) copy
mat4x4 vc;
memcpy(vc,v,sizeof(vc));
mat4x4_translate_in_place(vc,player->transform->position->x,player->transform->position->y,player->transform->position->z);
// rotation from direction to quart to model matrix apply
//--Vec3 dir = eulerToDirection(player->transform->rotation);
// rotation is already set to dir from camera
// rotation as direction is calculated here and in main, getdirection in custom.c only used once in main.c
Vec3 dir = {
player->transform->rotation->x,
0,
//player->transform->rotation->y,
player->transform->rotation->z,
};
Quaternion q = directionToQuaternion(dir);
mat4x4 RotationMatrix;
QuaternionToMat4(RotationMatrix,&q);
mat4x4_mul(m, m, RotationMatrix);
// apply scale to model matrix
applyScalingToModel(m, cubeScale, cubeScale, cubeScale);
execRenderModePerspective(vc); // custom view for position sets mvp
//memcpy(cube_mat4,mvp,sizeof(mat4x4));
// position
//Vec3 EulerAngles = {90, 45, 0};
//Quaternion q = ToQuaternion(EulerAngles);
//mat4x4_scale(cube_mat4, cube_mat4, .25f);
//printf("dir x:%f, y:%f, z:%f\n",dir.x,dir.y,dir.z);
RenderBoundBox(-1.0f,-1.0f,-1.0f,1.0f,1.0f,1.0f,1,mvp);
//RenderBoundBox(-1.0f,-1.0f,-1.0f,1.0f,1.0f,1.0f,1,cube_mat4);
if(zoomDist<= 0.01f)
return 0; // hide first person mode
//setUniform4m(&programCube, "MVP", mvp);
setUniform4m(&programCube, "MVP", mvp);
setUniform3f(&programCube,"sunPos", sunpos.x, sunpos.y, sunpos.z);
setUniform3f(&programCube,"moonPos", moonpos.x, moonpos.y,moonpos.z);
setUniform1i(&programCube,"colorOnly", 1);
setUniform3f(&programCube,"viewPos", camera->eye->position->x + player->transform->position->x, camera->eye->position->y + player->transform->position->y, camera->eye->position->z + player->transform->position->z);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(cube_array);
//glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
// Draw the triangle !
//glBindTexture(GL_TEXTURE_2D, texture1);
glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles -> 6 squares
//--glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
//printf("about to fail\n");
glBindVertexArray(0);
return 0;
}
int RenderBlock(Vec3 *pos, Vec3 *scale) {
//setUniform1i(&programCube, "texture1", 0);
//
setRenderModePerspective();
// transate position in view matrix (v) copy
mat4x4 vc;
memcpy(vc,v,sizeof(vc));
mat4x4_translate_in_place(vc,pos->x, pos->y, pos->z);
// rotation from direction to quart to model matrix apply
//--Vec3 dir = eulerToDirection(player->transform->rotation);
// rotation is already set to dir from camera
// rotation as direction is calculated here and in main, getdirection in custom.c only used once in main.c
Vec3 dir = {
0,
1,
0,
};
Quaternion q = directionToQuaternion(dir);
mat4x4 RotationMatrix;
QuaternionToMat4(RotationMatrix,&q);
mat4x4_mul(m, m, RotationMatrix);
// apply scale to model matrix
applyScalingToModel(m, scale->x, scale->y, scale->z);
execRenderModePerspective(vc); // custom view for position sets mvp
setUniform4m(&programCube, "MVP", mvp);
//memcpy(cube_mat4,mvp,sizeof(mat4x4));
// position
//Vec3 EulerAngles = {90, 45, 0};
//Quaternion q = ToQuaternion(EulerAngles);
//mat4x4_scale(cube_mat4, cube_mat4, .25f);
//printf("dir x:%f, y:%f, z:%f\n",dir.x,dir.y,dir.z);
RenderBoundBox(-1.0f,-1.0f,-1.0f,1.0f,1.0f,1.0f,1,mvp);
//RenderBoundBox(-1.0f,-1.0f,-1.0f,1.0f,1.0f,1.0f,1,cube_mat4);
//glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
// Draw the triangle !
//glBindTexture(GL_TEXTURE_2D, texture1);
glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles -> 6 squares
//--glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
//printf("about to fail\n");
//glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
return 0;
}
int RenderStair() {
int stairSteps=25;
float stepsize=5.0f;
float stepheight=2.0f;
if(initStairs==0) { // first run
// min x, min y, min z, max x, max y, max z, radius
// x y x, w, h, d
block_colliders=malloc(sizeof(float)*stairSteps*6);
}
Vec3 *pos=malloc(sizeof(Vec3));
Vec3 *scale=malloc(sizeof(Vec3));
scale->x = stepsize;
scale->y = stepheight/2;
scale->z = stepsize;
glUseProgram(0);
glUseProgram(programCube);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
//setUniform4m(&programCube, "MVP", mvp);
setUniform3f(&programCube,"sunPos", sunpos.x, sunpos.y, sunpos.z);
setUniform3f(&programCube,"moonPos", moonpos.x, moonpos.y,moonpos.z);
setUniform1i(&programCube, "texture1", 0);
setUniform1i(&programCube,"colorOnly", 0);
setUniform3f(&programCube,"viewPos", camera->eye->position->x + player->transform->position->x, camera->eye->position->y + player->transform->position->y, camera->eye->position->z + player->transform->position->z);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(cube_array);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, terrainTextures[0]);
//glBindTexture(GL_TEXTURE_2D, textureGrass1);
for(int i=0;i<stairSteps;++i) {
pos->x = -((stairSteps/2)*(stepsize*2))+(i*(stepsize*2)); // center
pos->y = 8.0f + (i*stepheight);
pos->z = 192.0f; // direction RED in grid
RenderBlock(pos,scale);
if(initStairs==0) { // first run
//--block_colliders[i*7] = pos->x - stepsize; //min x
//--block_colliders[i*7+1] = pos->y - stepsize; //min y
//--block_colliders[i*7+2] = pos->z - stepsize; //min z
//--block_colliders[i*7+3] = pos->x + stepsize; //max x
//--block_colliders[i*7+4] = pos->y + stepsize; //max y
//--block_colliders[i*7+5] = pos->z + stepsize; //maz z
block_colliders[i*6] = pos->x;
block_colliders[i*6+1] = pos->y;
block_colliders[i*6+2] = pos->z;
block_colliders[i*6+3] = stepsize;
block_colliders[i*6+4] = stepheight/2;
block_colliders[i*6+5] = stepsize;
//printf("adding block data stair\n");
}
}
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
free(pos);
free(scale);
if(initStairs==0) { // first run
initStairs=1;
}
return 0;
}
Top