add OpenGL 2.0 and 3.3 Core renderers
This commit is contained in:
@@ -0,0 +1,171 @@
|
|||||||
|
#include "gl20_renderer.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../../src/libsm64.h"
|
||||||
|
#include "../renderer.h"
|
||||||
|
#include "../context.h"
|
||||||
|
#include "../level.h"
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
static void load_collision_mesh( CollisionMesh *mesh )
|
||||||
|
{
|
||||||
|
mesh->num_vertices = 3 * surfaces_count;
|
||||||
|
mesh->position = malloc( sizeof( float ) * surfaces_count * 9 );
|
||||||
|
mesh->normal = malloc( sizeof( float ) * surfaces_count * 9 );
|
||||||
|
mesh->color = malloc( sizeof( float ) * surfaces_count * 9 );
|
||||||
|
mesh->index = malloc( sizeof( uint16_t ) * surfaces_count * 3 );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < surfaces_count; ++i )
|
||||||
|
{
|
||||||
|
const struct SM64Surface *surf = &surfaces[i];
|
||||||
|
|
||||||
|
float x1 = mesh->position[9*i+0] = surf->vertices[0][0];
|
||||||
|
float y1 = mesh->position[9*i+1] = surf->vertices[0][1];
|
||||||
|
float z1 = mesh->position[9*i+2] = surf->vertices[0][2];
|
||||||
|
float x2 = mesh->position[9*i+3] = surf->vertices[1][0];
|
||||||
|
float y2 = mesh->position[9*i+4] = surf->vertices[1][1];
|
||||||
|
float z2 = mesh->position[9*i+5] = surf->vertices[1][2];
|
||||||
|
float x3 = mesh->position[9*i+6] = surf->vertices[2][0];
|
||||||
|
float y3 = mesh->position[9*i+7] = surf->vertices[2][1];
|
||||||
|
float z3 = mesh->position[9*i+8] = surf->vertices[2][2];
|
||||||
|
|
||||||
|
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
||||||
|
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
||||||
|
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
||||||
|
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
||||||
|
nx /= mag;
|
||||||
|
ny /= mag;
|
||||||
|
nz /= mag;
|
||||||
|
|
||||||
|
mesh->normal[9*i+0] = nx;
|
||||||
|
mesh->normal[9*i+1] = ny;
|
||||||
|
mesh->normal[9*i+2] = nz;
|
||||||
|
mesh->normal[9*i+3] = nx;
|
||||||
|
mesh->normal[9*i+4] = ny;
|
||||||
|
mesh->normal[9*i+5] = nz;
|
||||||
|
mesh->normal[9*i+6] = nx;
|
||||||
|
mesh->normal[9*i+7] = ny;
|
||||||
|
mesh->normal[9*i+8] = nz;
|
||||||
|
|
||||||
|
for (int j=0; j<9; j++)
|
||||||
|
mesh->color[9*i+j] = (0.5 + 0.25 * 1) * (.5+.5*mesh->normal[9*i+j]);
|
||||||
|
|
||||||
|
mesh->index[3*i+0] = 3*i+0;
|
||||||
|
mesh->index[3*i+1] = 3*i+1;
|
||||||
|
mesh->index[3*i+2] = 3*i+2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
|
||||||
|
{
|
||||||
|
mesh->index = malloc( 3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t) );
|
||||||
|
for( int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i )
|
||||||
|
mesh->index[i] = i;
|
||||||
|
|
||||||
|
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
|
||||||
|
{
|
||||||
|
if( mesh->index == NULL )
|
||||||
|
load_mario_mesh( mesh, marioGeo );
|
||||||
|
|
||||||
|
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, marioGeo->position);
|
||||||
|
glNormalPointer(GL_FLOAT, 0, marioGeo->normal);
|
||||||
|
glColorPointer(3, GL_FLOAT, 0, marioGeo->color);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, marioGeo->uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gl20_init(RenderState *renderState, uint8_t *marioTexture)
|
||||||
|
{
|
||||||
|
load_collision_mesh( &renderState->collision );
|
||||||
|
|
||||||
|
glEnable( GL_CULL_FACE );
|
||||||
|
glCullFace( GL_BACK );
|
||||||
|
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
|
||||||
|
glDepthMask( GL_TRUE );
|
||||||
|
glDepthFunc( GL_LEQUAL );
|
||||||
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
glColor4f(1,1,1,1);
|
||||||
|
|
||||||
|
glGenTextures( 1, &renderState->mario_texture );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gl20_draw(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo)
|
||||||
|
{
|
||||||
|
mat4 model, view, projection;
|
||||||
|
glm_perspective( 45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection );
|
||||||
|
glm_translate( view, (float*)camPos );
|
||||||
|
glm_lookat( (float*)camPos, (float*)marioState->position, (vec3){0,1,0}, view );
|
||||||
|
glm_mat4_identity( model );
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadMatrixf((GLfloat*)projection);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadMatrixf((GLfloat*)view);
|
||||||
|
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
|
// draw world
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, renderState->collision.position);
|
||||||
|
glNormalPointer(GL_FLOAT, 0, renderState->collision.normal);
|
||||||
|
glColorPointer(3, GL_FLOAT, 0, renderState->collision.color);
|
||||||
|
glDrawElements(GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index);
|
||||||
|
|
||||||
|
// create lighting on the scene
|
||||||
|
GLfloat light_position[] = { camPos[0], camPos[1], camPos[2], 1 };
|
||||||
|
GLfloat light_diffuse[] = { 0.6f, 0.6f, 0.6f, 1 };
|
||||||
|
GLfloat light_model[] = { 0.5f, 0.5f, 0.5f, 1 };
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
||||||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
|
||||||
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_model);
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
|
||||||
|
// first, draw geometry without Mario's texture.
|
||||||
|
update_mario_mesh( &renderState->mario, marioGeo );
|
||||||
|
uint32_t triangleSize = renderState->mario.num_vertices;
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
|
||||||
|
|
||||||
|
// now disable the color array and enable the texture.
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
|
||||||
|
glMatrixMode(GL_TEXTURE);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Renderer gl20_renderer = {
|
||||||
|
gl20_init,
|
||||||
|
gl20_draw
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef GL20_RENDERER_H
|
||||||
|
#define GL20_RENDERER_H
|
||||||
|
|
||||||
|
extern struct Renderer gl20_renderer;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,313 @@
|
|||||||
|
#include "gl33core_renderer.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../../src/libsm64.h"
|
||||||
|
#include "../renderer.h"
|
||||||
|
#include "../context.h"
|
||||||
|
#include "../cglm.h"
|
||||||
|
#include "../level.h"
|
||||||
|
|
||||||
|
static const char *MARIO_SHADER =
|
||||||
|
"\n uniform mat4 view;"
|
||||||
|
"\n uniform mat4 projection;"
|
||||||
|
"\n uniform sampler2D marioTex;"
|
||||||
|
"\n "
|
||||||
|
"\n v2f vec3 v_color;"
|
||||||
|
"\n v2f vec3 v_normal;"
|
||||||
|
"\n v2f vec3 v_light;"
|
||||||
|
"\n v2f vec2 v_uv;"
|
||||||
|
"\n "
|
||||||
|
"\n #ifdef VERTEX"
|
||||||
|
"\n "
|
||||||
|
"\n layout(location = 0) in vec3 position;"
|
||||||
|
"\n layout(location = 1) in vec3 normal;"
|
||||||
|
"\n layout(location = 2) in vec3 color;"
|
||||||
|
"\n layout(location = 3) in vec2 uv;"
|
||||||
|
"\n "
|
||||||
|
"\n void main()"
|
||||||
|
"\n {"
|
||||||
|
"\n v_color = color;"
|
||||||
|
"\n v_normal = normal;"
|
||||||
|
"\n v_light = transpose( mat3( view )) * normalize( vec3( 1 ));"
|
||||||
|
"\n v_uv = uv;"
|
||||||
|
"\n "
|
||||||
|
"\n gl_Position = projection * view * vec4( position, 1. );"
|
||||||
|
"\n }"
|
||||||
|
"\n "
|
||||||
|
"\n #endif"
|
||||||
|
"\n #ifdef FRAGMENT"
|
||||||
|
"\n "
|
||||||
|
"\n out vec4 color;"
|
||||||
|
"\n "
|
||||||
|
"\n void main() "
|
||||||
|
"\n {"
|
||||||
|
"\n float light = .5 + .5 * clamp( dot( v_normal, v_light ), 0., 1. );"
|
||||||
|
"\n vec4 texColor = texture2D( marioTex, v_uv );"
|
||||||
|
"\n vec3 mainColor = mix( v_color, texColor.rgb, texColor.a ); // v_uv.x >= 0. ? texColor.a : 0. );"
|
||||||
|
"\n color = vec4( mainColor * light, 1 );"
|
||||||
|
"\n }"
|
||||||
|
"\n "
|
||||||
|
"\n #endif"
|
||||||
|
;
|
||||||
|
static const char *WORLD_SHADER =
|
||||||
|
"\n uniform mat4 model;"
|
||||||
|
"\n uniform mat4 view;"
|
||||||
|
"\n uniform mat4 projection;"
|
||||||
|
"\n uniform sampler2D tex;"
|
||||||
|
"\n "
|
||||||
|
"\n v2f vec3 v_normal;"
|
||||||
|
"\n v2f vec3 v_worldPos;"
|
||||||
|
"\n "
|
||||||
|
"\n #ifdef VERTEX"
|
||||||
|
"\n "
|
||||||
|
"\n layout(location = 0) in vec3 position;"
|
||||||
|
"\n layout(location = 1) in vec3 normal;"
|
||||||
|
"\n "
|
||||||
|
"\n void main()"
|
||||||
|
"\n {"
|
||||||
|
"\n v_normal = inverse(mat3(model)) * normal;"
|
||||||
|
"\n vec4 worldPos4 = model * vec4(position, 1.);"
|
||||||
|
"\n v_worldPos = worldPos4.xyz;"
|
||||||
|
"\n gl_Position = projection * view * worldPos4;"
|
||||||
|
"\n }"
|
||||||
|
"\n "
|
||||||
|
"\n #endif"
|
||||||
|
"\n #ifdef FRAGMENT"
|
||||||
|
"\n "
|
||||||
|
"\n vec3 tri( vec3 x )"
|
||||||
|
"\n {"
|
||||||
|
"\n return abs(x-floor(x)-.5);"
|
||||||
|
"\n } "
|
||||||
|
"\n float surfFunc( vec3 p )"
|
||||||
|
"\n {"
|
||||||
|
"\n float n = dot(tri(p*.15 + tri(p.yzx*.075)), vec3(.444));"
|
||||||
|
"\n p = p*1.5773 - n;"
|
||||||
|
"\n p.yz = vec2(p.y + p.z, p.z - p.y) * .866;"
|
||||||
|
"\n p.xz = vec2(p.x + p.z, p.z - p.x) * .866;"
|
||||||
|
"\n n += dot(tri(p*.225 + tri(p.yzx*.1125)), vec3(.222)); "
|
||||||
|
"\n return abs(n-.5)*1.9 + (1.-abs(sin(n*9.)))*.05;"
|
||||||
|
"\n }"
|
||||||
|
"\n "
|
||||||
|
"\n const vec3 light_x = vec3(-1.0, 0.4, 0.9);"
|
||||||
|
"\n "
|
||||||
|
"\n out vec4 color;"
|
||||||
|
"\n "
|
||||||
|
"\n void main() "
|
||||||
|
"\n {"
|
||||||
|
"\n float surfy = surfFunc( v_worldPos / 50. );"
|
||||||
|
"\n float brightness = smoothstep( .2, .3, surfy );"
|
||||||
|
"\n "
|
||||||
|
"\n color = vec4( (0.5 + 0.25 * brightness) * (.5+.5*v_normal), 1 );"
|
||||||
|
"\n }"
|
||||||
|
"\n "
|
||||||
|
"\n #endif"
|
||||||
|
;
|
||||||
|
|
||||||
|
static void load_collision_mesh( CollisionMesh *mesh )
|
||||||
|
{
|
||||||
|
mesh->num_vertices = 3 * surfaces_count;
|
||||||
|
mesh->position = malloc( sizeof( float ) * surfaces_count * 9 );
|
||||||
|
mesh->normal = malloc( sizeof( float ) * surfaces_count * 9 );
|
||||||
|
mesh->index = malloc( sizeof( uint16_t ) * surfaces_count * 3 );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < surfaces_count; ++i )
|
||||||
|
{
|
||||||
|
const struct SM64Surface *surf = &surfaces[i];
|
||||||
|
|
||||||
|
float x1 = mesh->position[9*i+0] = surf->vertices[0][0];
|
||||||
|
float y1 = mesh->position[9*i+1] = surf->vertices[0][1];
|
||||||
|
float z1 = mesh->position[9*i+2] = surf->vertices[0][2];
|
||||||
|
float x2 = mesh->position[9*i+3] = surf->vertices[1][0];
|
||||||
|
float y2 = mesh->position[9*i+4] = surf->vertices[1][1];
|
||||||
|
float z2 = mesh->position[9*i+5] = surf->vertices[1][2];
|
||||||
|
float x3 = mesh->position[9*i+6] = surf->vertices[2][0];
|
||||||
|
float y3 = mesh->position[9*i+7] = surf->vertices[2][1];
|
||||||
|
float z3 = mesh->position[9*i+8] = surf->vertices[2][2];
|
||||||
|
|
||||||
|
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
|
||||||
|
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
|
||||||
|
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
|
||||||
|
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
|
||||||
|
nx /= mag;
|
||||||
|
ny /= mag;
|
||||||
|
nz /= mag;
|
||||||
|
|
||||||
|
mesh->normal[9*i+0] = nx;
|
||||||
|
mesh->normal[9*i+1] = ny;
|
||||||
|
mesh->normal[9*i+2] = nz;
|
||||||
|
mesh->normal[9*i+3] = nx;
|
||||||
|
mesh->normal[9*i+4] = ny;
|
||||||
|
mesh->normal[9*i+5] = nz;
|
||||||
|
mesh->normal[9*i+6] = nx;
|
||||||
|
mesh->normal[9*i+7] = ny;
|
||||||
|
mesh->normal[9*i+8] = nz;
|
||||||
|
|
||||||
|
mesh->index[3*i+0] = 3*i+0;
|
||||||
|
mesh->index[3*i+1] = 3*i+1;
|
||||||
|
mesh->index[3*i+2] = 3*i+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays( 1, &mesh->vao );
|
||||||
|
glBindVertexArray( mesh->vao );
|
||||||
|
|
||||||
|
#define X( loc, buff, arr, type ) do { \
|
||||||
|
glGenBuffers( 1, &buff ); \
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, buff ); \
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, mesh->num_vertices*sizeof( type ), arr, GL_STATIC_DRAW ); \
|
||||||
|
glEnableVertexAttribArray( loc ); \
|
||||||
|
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), NULL ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
X( 0, mesh->position_buffer, mesh->position, vec3 );
|
||||||
|
X( 1, mesh->normal_buffer, mesh->normal, vec3 );
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
|
||||||
|
{
|
||||||
|
mesh->index = malloc( 3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t) );
|
||||||
|
for( int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i )
|
||||||
|
mesh->index[i] = i;
|
||||||
|
|
||||||
|
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
|
||||||
|
|
||||||
|
glGenVertexArrays( 1, &mesh->vao );
|
||||||
|
glBindVertexArray( mesh->vao );
|
||||||
|
|
||||||
|
#define X( loc, buff, arr, type ) do { \
|
||||||
|
glGenBuffers( 1, &buff ); \
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, buff ); \
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof( type ) * 3 * SM64_GEO_MAX_TRIANGLES, arr, GL_DYNAMIC_DRAW ); \
|
||||||
|
glEnableVertexAttribArray( loc ); \
|
||||||
|
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), NULL ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
|
X( 0, mesh->position_buffer, marioGeo->position, vec3 );
|
||||||
|
X( 1, mesh->normal_buffer, marioGeo->normal, vec3 );
|
||||||
|
X( 2, mesh->color_buffer, marioGeo->color, vec3 );
|
||||||
|
X( 3, mesh->uv_buffer, marioGeo->uv, vec2 );
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
|
||||||
|
{
|
||||||
|
if( mesh->index == NULL )
|
||||||
|
load_mario_mesh( mesh, marioGeo );
|
||||||
|
|
||||||
|
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
|
||||||
|
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, mesh->position_buffer );
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->position, GL_DYNAMIC_DRAW );
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, mesh->normal_buffer );
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->normal, GL_DYNAMIC_DRAW );
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, mesh->color_buffer );
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->color, GL_DYNAMIC_DRAW );
|
||||||
|
glBindBuffer( GL_ARRAY_BUFFER, mesh->uv_buffer );
|
||||||
|
glBufferData( GL_ARRAY_BUFFER, sizeof( vec2 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->uv, GL_DYNAMIC_DRAW );
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLuint shader_compile( const char *shaderContents, size_t shaderContentsLength, GLenum shaderType )
|
||||||
|
{
|
||||||
|
const GLchar *shaderDefine = shaderType == GL_VERTEX_SHADER
|
||||||
|
? "\n#version 330\n#define VERTEX \n#define v2f out\n"
|
||||||
|
: "\n#version 330\n#define FRAGMENT\n#define v2f in \n";
|
||||||
|
|
||||||
|
const GLchar *shaderStrings[2] = { shaderDefine, shaderContents };
|
||||||
|
GLint shaderStringLengths[2] = { strlen( shaderDefine ), (GLint)shaderContentsLength };
|
||||||
|
|
||||||
|
GLuint shader = glCreateShader( shaderType );
|
||||||
|
glShaderSource( shader, 2, shaderStrings, shaderStringLengths );
|
||||||
|
glCompileShader( shader );
|
||||||
|
|
||||||
|
GLint isCompiled;
|
||||||
|
glGetShaderiv( shader, GL_COMPILE_STATUS, &isCompiled );
|
||||||
|
if( isCompiled == GL_FALSE )
|
||||||
|
{
|
||||||
|
GLint maxLength;
|
||||||
|
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &maxLength );
|
||||||
|
char *log = (char*)malloc( maxLength );
|
||||||
|
glGetShaderInfoLog( shader, maxLength, &maxLength, log );
|
||||||
|
|
||||||
|
printf( "Error in shader: %s\n%s\n%s\n", log, shaderStrings[0], shaderStrings[1] );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLuint shader_load( const char *shaderContents )
|
||||||
|
{
|
||||||
|
GLuint result;
|
||||||
|
GLuint vert = shader_compile( shaderContents, strlen( shaderContents ), GL_VERTEX_SHADER );
|
||||||
|
GLuint frag = shader_compile( shaderContents, strlen( shaderContents ), GL_FRAGMENT_SHADER );
|
||||||
|
|
||||||
|
GLuint ref = glCreateProgram();
|
||||||
|
glAttachShader( ref, vert );
|
||||||
|
glAttachShader( ref, frag );
|
||||||
|
|
||||||
|
glLinkProgram ( ref );
|
||||||
|
glDetachShader( ref, vert );
|
||||||
|
glDetachShader( ref, frag );
|
||||||
|
result = ref;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gl33core_init(RenderState *renderState, uint8_t *marioTexture)
|
||||||
|
{
|
||||||
|
load_collision_mesh( &renderState->collision );
|
||||||
|
renderState->world_shader = shader_load( WORLD_SHADER );
|
||||||
|
renderState->mario_shader = shader_load( MARIO_SHADER );
|
||||||
|
|
||||||
|
glEnable( GL_CULL_FACE );
|
||||||
|
glCullFace( GL_BACK );
|
||||||
|
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
|
||||||
|
glDepthMask( GL_TRUE );
|
||||||
|
glDepthFunc( GL_LEQUAL );
|
||||||
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
|
||||||
|
glGenTextures( 1, &renderState->mario_texture );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gl33core_draw(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo)
|
||||||
|
{
|
||||||
|
update_mario_mesh( &renderState->mario, marioGeo );
|
||||||
|
|
||||||
|
mat4 model, view, projection;
|
||||||
|
glm_perspective( 45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection );
|
||||||
|
glm_translate( view, (float*)camPos );
|
||||||
|
glm_lookat( (float*)camPos, (float*)marioState->position, (vec3){0,1,0}, view );
|
||||||
|
glm_mat4_identity( model );
|
||||||
|
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
|
||||||
|
glUseProgram( renderState->world_shader );
|
||||||
|
glBindVertexArray( renderState->collision.vao );
|
||||||
|
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "model" ), 1, GL_FALSE, (GLfloat*)model );
|
||||||
|
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "view" ), 1, GL_FALSE, (GLfloat*)view );
|
||||||
|
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "projection" ), 1, GL_FALSE, (GLfloat*)projection );
|
||||||
|
glDrawElements( GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index );
|
||||||
|
|
||||||
|
glUseProgram( renderState->mario_shader );
|
||||||
|
glActiveTexture( GL_TEXTURE0 );
|
||||||
|
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
|
||||||
|
glBindVertexArray( renderState->mario.vao );
|
||||||
|
glUniformMatrix4fv( glGetUniformLocation( renderState->mario_shader, "view" ), 1, GL_FALSE, (GLfloat*)view );
|
||||||
|
glUniformMatrix4fv( glGetUniformLocation( renderState->mario_shader, "projection" ), 1, GL_FALSE, (GLfloat*)projection );
|
||||||
|
glUniform1i( glGetUniformLocation( renderState->mario_shader, "marioTex" ), 0 );
|
||||||
|
glDrawElements( GL_TRIANGLES, renderState->mario.num_vertices, GL_UNSIGNED_SHORT, renderState->mario.index );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Renderer gl33core_renderer = {
|
||||||
|
gl33core_init,
|
||||||
|
gl33core_draw
|
||||||
|
};
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef GL33CORE_RENDERER_H
|
||||||
|
#define GL33CORE_RENDERER_H
|
||||||
|
|
||||||
|
extern struct Renderer gl33core_renderer;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef RENDERER_H
|
||||||
|
#define RENDERER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "../src/libsm64.h"
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
#include "cglm.h"
|
||||||
|
|
||||||
|
typedef struct CollisionMesh
|
||||||
|
{
|
||||||
|
size_t num_vertices;
|
||||||
|
float *position;
|
||||||
|
float *normal;
|
||||||
|
float *color;
|
||||||
|
uint16_t *index;
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
GLuint position_buffer;
|
||||||
|
GLuint normal_buffer;
|
||||||
|
}
|
||||||
|
CollisionMesh;
|
||||||
|
|
||||||
|
typedef struct MarioMesh
|
||||||
|
{
|
||||||
|
size_t num_vertices;
|
||||||
|
uint16_t *index;
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
GLuint position_buffer;
|
||||||
|
GLuint normal_buffer;
|
||||||
|
GLuint color_buffer;
|
||||||
|
GLuint uv_buffer;
|
||||||
|
}
|
||||||
|
MarioMesh;
|
||||||
|
|
||||||
|
typedef struct RenderState
|
||||||
|
{
|
||||||
|
CollisionMesh collision;
|
||||||
|
MarioMesh mario;
|
||||||
|
GLuint world_shader;
|
||||||
|
GLuint mario_shader;
|
||||||
|
GLuint mario_texture;
|
||||||
|
}
|
||||||
|
RenderState;
|
||||||
|
|
||||||
|
|
||||||
|
struct Renderer
|
||||||
|
{
|
||||||
|
void (*init)(RenderState *renderState, uint8_t *marioTexture);
|
||||||
|
void (*draw)(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user