aboutsummaryrefslogtreecommitdiff
path: root/08-august/src/renderer/renderer.c
blob: 2ea4426b2bf7e778ae9d691c672f86c8829d7ddc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "renderer.h"
#include "../util/util_time.h"

#include <string.h>

#define MAX_LIGHTS 4

void Render_Init()
{

}

void Render_LoadLights(Shader_Layout *layout, const light_t *lights, int n)
{
    vec3_t light_positions[MAX_LIGHTS];
    vec4_t light_colors[MAX_LIGHTS];
    vec3_t attenuation[MAX_LIGHTS];

    /* Default light in case we are not given enough lights (n < 4) */
    const light_t defaultLight = { {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f} };

    int i;
    for(i = 0; i < MAX_LIGHTS; i++)
    {
        if(i < MAX_LIGHTS)
        {
            light_positions[i] = lights[i].position;
            light_colors[i] = lights[i].color;
            attenuation[i] = lights[i].attenuation;
        }
        else
        {
            light_positions[i] = defaultLight.position;
            light_colors[i] = defaultLight.color;
            attenuation[i] = defaultLight.attenuation;
        }

    }

    glUniform3fv(layout->lightPosition, MAX_LIGHTS, (float*)light_positions);
    glUniform4fv(layout->lightColor, MAX_LIGHTS, (float*)light_colors);
    glUniform3fv(layout->lightAttenuation, MAX_LIGHTS, (float*)attenuation);

}

void Render_DrawEntity(Shader_Layout *layout, mat4_t *projectedViewMatrix, entity_t *entity)
{
    glBindVertexArray(entity->shape->vao);

    /*We need the model to world matrix in our shader in order to rotate the normals*/
    mat4_t modelTransform = Entity_GetModelTransform(entity);
    glUniformMatrix4fv(layout->modelToWorld, 1, GL_FALSE, modelTransform.data);

    mat4_t totalMatrix = mat4_mul(projectedViewMatrix, &modelTransform);
    glUniformMatrix4fv(layout->totalTransform, 1, GL_FALSE, totalMatrix.data);

    glActiveTexture(GL_TEXTURE0);
    glUniform1i(layout->Texture, 0);
    glBindTexture(GL_TEXTURE_2D, entity->texture);

    glDrawElements(GL_TRIANGLES, entity->shape->num_indices, GL_UNSIGNED_SHORT, NULL);
    glBindVertexArray(0);
}

/******************************************************************************
*                                                                             *
* Function Name: Render_DrawTerrain                                           *
*                                                                             *
* Specific shader layout                                                      *
* -> extra0 Texture_Background                                                *
* -> extra1 Texture_R                                                         *
* -> extra2 Texture_G                                                         *
* -> extra3 Texture_B                                                         *
* -> extra4 Texture_BlendMap                                                  *
*                                                                             *
*******************************************************************************/

void Render_DrawTerrain(Shader_Layout *layout, mat4_t *projectedViewMatrix, terrain_t *terrain)
{
    glBindVertexArray(terrain->shape->vao);

    /* We need the model to world matrix in our shader in order to rotate the normals */
    mat4_t modelTransform = mat4_translate(&terrain->position);
    glUniformMatrix4fv(layout->modelToWorld, 1, GL_FALSE, modelTransform.data);

    mat4_t totalMatrix = mat4_mul(projectedViewMatrix, &modelTransform);
    glUniformMatrix4fv(layout->totalTransform, 1, GL_FALSE, totalMatrix.data);

    /** Set textures for the terrain **/

    glUniform1i(layout->extra0, 0);
    glUniform1i(layout->extra1, 1);
    glUniform1i(layout->extra2, 2);
    glUniform1i(layout->extra3, 3);
    glUniform1i(layout->extra4, 4);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, terrain->textures.texture[0]);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, terrain->textures.texture[1]);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, terrain->textures.texture[2]);
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, terrain->textures.texture[3]);
    glActiveTexture(GL_TEXTURE4);
    glBindTexture(GL_TEXTURE_2D, terrain->blendmap);

    /************************************************************/

    glDrawElements(GL_TRIANGLES, terrain->shape->num_indices, GL_UNSIGNED_SHORT, NULL);

    glBindVertexArray(0);
}

void Render_DrawSky(Shader_Layout *layout, mat4_t *viewMatrix, mat4_t *projectionMatrix, skybox_t *sky)
{
    glBindVertexArray(sky->cube->vao);

    mat4_t myViewMatrix = *viewMatrix;
    sky->rotation += SKYBOX_ROTATION_SPEED * Time_GetFrameTime();
    mat4_t rotateMatrix = mat4_rotate_y(sky->rotation);

    /* We don't want to move the skybox around (We want it to stay with the camera in the midle),
       just rotate it with the camera so we remove the translations components of the matrix */

    myViewMatrix.data[0 + 3 * 4] = 0.0f;
    myViewMatrix.data[1 + 3 * 4] = 0.0f;
    myViewMatrix.data[2 + 3 * 4] = 0.0f;

    myViewMatrix = mat4_mul(&myViewMatrix, &rotateMatrix);
    mat4_t totalTransform = mat4_mul(projectionMatrix, &myViewMatrix);

    glUniformMatrix4fv(layout->totalTransform, 1, GL_FALSE, totalTransform.data );

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, sky->texture);
    glUniform1i(layout->Texture, 0);

    glDrawArrays(GL_TRIANGLES, 0, 36);

    glBindVertexArray(0);
}

void Render_Quit()
{

}