|
| 1 | +#define GL_GLEXT_PROTOTYPES |
| 2 | +#include "opengx.h" |
| 3 | + |
| 4 | +#include <SDL_opengl.h> |
| 5 | +#include <gccore.h> |
| 6 | +#include <stdio.h> |
| 7 | +#include <stdlib.h> |
| 8 | + |
| 9 | +static inline GXColor gxcol_new_fv(const float *components) |
| 10 | +{ |
| 11 | + GXColor c = { |
| 12 | + (u8)(components[0] * 255.0f), |
| 13 | + (u8)(components[1] * 255.0f), |
| 14 | + (u8)(components[2] * 255.0f), |
| 15 | + (u8)(components[3] * 255.0f) |
| 16 | + }; |
| 17 | + return c; |
| 18 | +} |
| 19 | + |
| 20 | +typedef struct { |
| 21 | + GLint mvp_loc; |
| 22 | + GLint normal_matrix_loc; |
| 23 | + GLint mat_color_loc; |
| 24 | + GLint light_pos_loc; |
| 25 | +} Gl2GearsData; |
| 26 | + |
| 27 | +static void gl2gears_setup_draw(GLuint program, const OgxDrawData *draw_data, |
| 28 | + void *user_data) |
| 29 | +{ |
| 30 | + Gl2GearsData *data = user_data; |
| 31 | + float m[16]; |
| 32 | + glGetUniformfv(program, data->mvp_loc, m); |
| 33 | + float normal_matrix[16]; |
| 34 | + glGetUniformfv(program, data->normal_matrix_loc, normal_matrix); |
| 35 | + float colorf[4]; |
| 36 | + glGetUniformfv(program, data->mat_color_loc, colorf); |
| 37 | + float light_dir[4]; |
| 38 | + glGetUniformfv(program, data->light_pos_loc, light_dir); |
| 39 | + ogx_set_mvp_matrix(m); |
| 40 | + |
| 41 | + Mtx normalm; |
| 42 | + ogx_matrix_gl_to_mtx(normal_matrix, normalm); |
| 43 | + GX_LoadNrmMtxImm(normalm, GX_PNMTX0); |
| 44 | + |
| 45 | + GXLightObj light; |
| 46 | + // Increase distance to simulate a directional light |
| 47 | + float light_pos[3] = { |
| 48 | + light_dir[0] * 100000, |
| 49 | + light_dir[1] * 100000, |
| 50 | + light_dir[2] * 100000, |
| 51 | + }; |
| 52 | + GX_InitLightPosv(&light, light_pos); |
| 53 | + GXColor white = { 255, 255, 255, 255 }; |
| 54 | + GX_InitLightColor(&light, white); |
| 55 | + GX_InitLightAttn(&light, 1, 0, 0, 1, 0, 0); // no attenuation |
| 56 | + GX_LoadLightObj(&light, 1); |
| 57 | + |
| 58 | + |
| 59 | + GXColor mat_color = gxcol_new_fv(colorf); |
| 60 | + GX_SetNumChans(1); |
| 61 | + GX_SetChanMatColor(GX_COLOR0A0, mat_color); |
| 62 | + GX_SetChanCtrl(GX_COLOR0A0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, |
| 63 | + 1, GX_DF_CLAMP, GX_AF_NONE); |
| 64 | + |
| 65 | + GX_SetNumTevStages(1); |
| 66 | + GX_SetNumTexGens(0); |
| 67 | + GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); |
| 68 | +} |
| 69 | + |
| 70 | +static bool shader_compile(GLuint shader) |
| 71 | +{ |
| 72 | + uint32_t source_hash = ogx_shader_get_source_hash(shader); |
| 73 | + |
| 74 | + fprintf(stderr, "%s:%d shader %x hash %08x\n", __FILE__, __LINE__, shader, source_hash); |
| 75 | + if (source_hash == 0x5b32d27f) { |
| 76 | + /* gl2gears.c vertex shader */ |
| 77 | + ogx_shader_add_uniforms(shader, 4, |
| 78 | + "ModelViewProjectionMatrix", GL_FLOAT_MAT4, |
| 79 | + "NormalMatrix", GL_FLOAT_MAT4, |
| 80 | + "LightSourcePosition", GL_FLOAT_VEC4, |
| 81 | + "MaterialColor", GL_FLOAT_VEC4); |
| 82 | + ogx_shader_add_attributes(shader, 2, |
| 83 | + "position", GL_FLOAT_VEC3, GX_VA_POS, |
| 84 | + "normal", GL_FLOAT_VEC3, GX_VA_NRM); |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +static GLenum link_program(GLuint program) |
| 89 | +{ |
| 90 | + GLuint shaders[2]; |
| 91 | + int count = 0; |
| 92 | + glGetAttachedShaders(program, 2, &count, shaders); |
| 93 | + uint32_t vertex_shader_hash = ogx_shader_get_source_hash(shaders[0]); |
| 94 | + if (vertex_shader_hash == 0x5b32d27f) { /* gl2gears */ |
| 95 | + Gl2GearsData *data = calloc(1, sizeof(Gl2GearsData)); |
| 96 | + data->mvp_loc = glGetUniformLocation(program, "ModelViewProjectionMatrix"); |
| 97 | + data->normal_matrix_loc = glGetUniformLocation(program, "NormalMatrix"); |
| 98 | + data->mat_color_loc = glGetUniformLocation(program, "MaterialColor"); |
| 99 | + data->light_pos_loc = glGetUniformLocation(program, "LightSourcePosition"); |
| 100 | + ogx_shader_program_set_user_data(program, data, free); |
| 101 | + ogx_shader_program_set_setup_draw_cb(program, gl2gears_setup_draw); |
| 102 | + } |
| 103 | + return GL_NO_ERROR; |
| 104 | +} |
| 105 | + |
| 106 | +const OgxProgramProcessor s_processor = { |
| 107 | + .compile_shader = shader_compile, |
| 108 | + .link_program = link_program, |
| 109 | +}; |
| 110 | + |
| 111 | +void setup_opengx_shaders() |
| 112 | +{ |
| 113 | + ogx_shader_register_program_processor(&s_processor); |
| 114 | +} |
0 commit comments