Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions src/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ struct VertexReaderBase {
format.attribute <= GX_VA_TEX7) {
/* Texture coordinates must be enable sequentially */
format.attribute = GX_VA_TEX0 + s_num_tex_arrays++;
/* And GX does not support more than two coordinates */
if (format.num_components > 2) format.num_components = 2;
}
GX_SetVtxDesc(format.attribute, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, format.attribute,
Expand Down Expand Up @@ -180,6 +182,11 @@ struct DirectVboReader: public VertexReaderBase {
}

void setup_draw() override {
if (format.attribute >= GX_VA_TEX0 &&
format.attribute <= GX_VA_TEX7) {
/* Texture coordinates must be enable sequentially */
format.attribute = GX_VA_TEX0 + s_num_tex_arrays++;
}
GX_SetArray(format.attribute, const_cast<char*>(data), stride);
GX_SetVtxDesc(format.attribute, GX_INDEX16);
GX_SetVtxAttrFmt(GX_VTXFMT0, format.attribute,
Expand Down Expand Up @@ -327,21 +334,21 @@ struct CoordVertexReader: public GenericVertexReader<T> {
using GenericVertexReader<T>::GenericVertexReader;

void process_element(int index) {
float x, y, z;
const T *ptr = elemAt(index);
x = *ptr++;
y = *ptr++;
if (format.num_components >= 3) {
if (format.num_components == 4) {
float x, y, z, w;
x = *ptr++;
y = *ptr++;
z = *ptr++;
if (format.num_components == 4) {
float w = *ptr++;
x /= w;
y /= w;
z /= w;
}
w = *ptr++;
x /= w;
y /= w;
z /= w;
GX_Position3f32(x, y, z);
} else {
GX_Position2f32(x, y);
for (int i = 0; i < format.num_components; i++, ptr++) {
wgPipe->F32 = float(*ptr++);
}
}
}
};
Expand Down
48 changes: 35 additions & 13 deletions src/gc_gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,13 +999,15 @@ void glPopMatrix(void)
}
memcpy(glparamstate.projection_matrix, glparamstate.projection_stack[glparamstate.cur_proj_mat], sizeof(Mtx44));
glparamstate.cur_proj_mat--;
break;
case 1:
if (glparamstate.cur_modv_mat < 0) {
set_error(GL_STACK_UNDERFLOW);
return;
}
memcpy(glparamstate.modelview_matrix, glparamstate.modelview_stack[glparamstate.cur_modv_mat], sizeof(Mtx));
glparamstate.cur_modv_mat--;
break;
case 2:
{
OgxTextureUnit *tu = active_tex_unit();
Expand Down Expand Up @@ -1049,6 +1051,8 @@ void glPushMatrix(void)
set_error(GL_STACK_OVERFLOW);
return;
}
memcpy(tu->matrix[tu->matrix_index + 1],
tu->matrix[tu->matrix_index], sizeof(Mtx));
tu->matrix_index++;
}
default:
Expand Down Expand Up @@ -1208,6 +1212,7 @@ void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
Mtx *target = NULL;
Mtx44 rot;
guVector axis = { x, y, z };
if (angle == 0.0f || (x == 0.0f && y == 0.0f && z == 0.0f)) return;
guMtxRotAxisDeg(rot, &axis, angle);

switch (glparamstate.matrixmode) {
Expand Down Expand Up @@ -1546,7 +1551,10 @@ void glDisableClientState(GLenum cap)
glparamstate.cs.normal_enabled = 0;
break;
case GL_TEXTURE_COORD_ARRAY:
glparamstate.cs.texcoord_enabled = 0;
{
int unit = glparamstate.cs.active_texture;
glparamstate.cs.texcoord_enabled &= ~(1 << unit);
}
break;
case GL_VERTEX_ARRAY:
glparamstate.cs.vertex_enabled = 0;
Expand All @@ -1570,7 +1578,10 @@ void glEnableClientState(GLenum cap)
glparamstate.cs.normal_enabled = 1;
break;
case GL_TEXTURE_COORD_ARRAY:
glparamstate.cs.texcoord_enabled = 1;
{
int unit = glparamstate.cs.active_texture;
glparamstate.cs.texcoord_enabled |= (1 << unit);
}
break;
case GL_VERTEX_ARRAY:
glparamstate.cs.vertex_enabled = 1;
Expand Down Expand Up @@ -2030,10 +2041,18 @@ static void setup_fog()

bool _ogx_setup_render_stages()
{
u8 raster_output, raster_reg_index;
if (glparamstate.texture_enabled) {
raster_reg_index = _ogx_gpu_resources->tevreg_first++;
raster_output = GX_TEVREG0 + raster_reg_index;
} else {
raster_output = GX_TEVPREV;
}

if (glparamstate.lighting.enabled) {
LightMasks light_mask = prepare_lighting();

GXColor color_zero = { 0, 0, 0, 0 };
GXColor color_black = { 0, 0, 0, 255 };
GXColor color_gamb = gxcol_new_fv(glparamstate.lighting.globalambient);

_ogx_gpu_resources->tevstage_first += 2;
Expand Down Expand Up @@ -2101,14 +2120,17 @@ bool _ogx_setup_render_stages()
light_mask.ambient_mask | light_mask.specular_mask , GX_DF_NONE, GX_AF_SPEC);
GX_SetChanAmbColor(GX_COLOR0A0, color_gamb);

// Color1 channel: Multiplies the light raster result with the vertex color. Ambient is set to register (which is zero)
// Color1 channel: Multiplies the light raster result with the vertex color. Ambient is set to register (which is black)
GX_SetChanCtrl(GX_COLOR1A1, GX_TRUE, GX_SRC_REG, vert_color_src, light_mask.diffuse_mask, GX_DF_CLAMP, GX_AF_SPOT);
GX_SetChanAmbColor(GX_COLOR1A1, color_zero);
GX_SetChanAmbColor(GX_COLOR1A1, color_black);

// STAGE 0: ambient*vert_color -> cprev
// In data: d: Raster Color, a: emission color
GX_SetTevColor(GX_TEVPREV, ecol);
GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
u8 emission_reg = _ogx_gpu_resources->tevreg_first++;
GX_SetTevColor(GX_TEVREG0 + emission_reg, ecol);
/* Multiply by two because there are alpha registers in between */
GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_C0 + emission_reg * 2,
GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
// Operation: Pass d
GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
Expand All @@ -2119,16 +2141,16 @@ bool _ogx_setup_render_stages()
// STAGE 1: diffuse*vert_color + cprev -> cprev
// In data: d: Raster Color a: CPREV
GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO);
// Operation: Sum a + d
GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, raster_output);
GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, raster_output);
// Select COLOR1A1 for the rasterizer, disable all textures
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORDNULL, GX_TEXMAP_DISABLE, GX_COLOR1A1);

if (glparamstate.texture_enabled) {
// Do not select any raster value, Texture 0 for texture rasterizer and TEXCOORD0 slot for tex coordinates
_ogx_setup_texture_stages(GX_CC_CPREV, GX_CA_APREV, GX_COLORNULL);
// Do not select any raster color channel
_ogx_setup_texture_stages(raster_reg_index, GX_COLORNULL);
}
} else {
// Unlit scene
Expand All @@ -2153,7 +2175,7 @@ bool _ogx_setup_render_stages()

if (glparamstate.texture_enabled) {
// Select COLOR0A0 for the rasterizer, Texture 0 for texture rasterizer and TEXCOORD0 slot for tex coordinates
_ogx_setup_texture_stages(GX_CC_RASC, GX_CA_RASA, GX_COLOR0A0);
_ogx_setup_texture_stages(raster_reg_index, GX_COLOR0A0);
} else {
// Use one stage only
_ogx_gpu_resources->tevstage_first += 1;
Expand Down
3 changes: 2 additions & 1 deletion src/getters.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const GLubyte *glGetString(GLenum name)
return "1.1";
case GL_EXTENSIONS:
return
"GL_ARB_multitexture"
"GL_ARB_multitexture "
"GL_ARB_vertex_buffer_object ";
default:
set_error(GL_INVALID_ENUM);
Expand Down Expand Up @@ -204,6 +204,7 @@ void glGetIntegerv(GLenum pname, GLint *params)
return;
case GL_MAX_TEXTURE_COORDS:
case GL_MAX_TEXTURE_IMAGE_UNITS:
case GL_MAX_TEXTURE_UNITS:
*params = MAX_TEXTURE_UNITS;
break;
case GL_MAX_TEXTURE_SIZE:
Expand Down
3 changes: 3 additions & 0 deletions src/gpu_resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ static void resources_init(OgxGpuResources *resources)
resources->kcolor_first = 0;
resources->kcolor_end = GX_KCOLOR_MAX;

resources->tevreg_first = 0;
resources->tevreg_end = GX_MAX_TEVREG - 1; /* we exclude GX_TEVPREV */

resources->texcoord_first = 0;
resources->texcoord_end = GX_MAXCOORD;

Expand Down
2 changes: 2 additions & 0 deletions src/gpu_resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ typedef struct {
uint8_t tevstage_end;
uint8_t kcolor_first;
uint8_t kcolor_end;
uint8_t tevreg_first;
uint8_t tevreg_end;
uint8_t texcoord_first;
uint8_t texcoord_end;
uint8_t pnmtx_first;
Expand Down
3 changes: 3 additions & 0 deletions src/pixel_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ struct PixelStreamBase {
virtual void write(GXColor color) = 0;
virtual void setup() {}

void *operator new(size_t size) { return malloc(size); }
void operator delete(void * p) { free(p); }

protected:
void *m_data;
int m_width;
Expand Down
9 changes: 6 additions & 3 deletions src/stencil.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,14 @@ static bool draw_op(uint16_t op,
glparamstate.dirty.bits.dirty_color_update = 1;

u8 stage = GX_TEVSTAGE0 + _ogx_gpu_resources->tevstage_first++;
GX_SetTevColor(GX_TEVPREV, drawColor);
u8 tevreg_index = _ogx_gpu_resources->tevreg_first++;
GX_SetTevColor(GX_TEVREG0 + tevreg_index, drawColor);
GX_SetTevOrder(stage, GX_TEXCOORDNULL, GX_TEXMAP_DISABLE, GX_COLOR0A0);
/* Pass the constant color */
GX_SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV);
GX_SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
GX_SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO,
GX_CC_C0 + tevreg_index * 2);
GX_SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO,
GX_CA_A0 + tevreg_index);
GX_SetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1,
GX_TRUE, GX_TEVPREV);
GX_SetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1,
Expand Down
3 changes: 3 additions & 0 deletions src/texel.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ struct Texel {
}
}

void *operator new(size_t size) { return malloc(size); }
void operator delete(void * p) { free(p); }

void *m_data;
int m_x;
int m_y;
Expand Down
11 changes: 6 additions & 5 deletions src/texture.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ typedef union {
(TEXTURE_USER_DATA(&texture.texobj).d.is_reserved)
#define TEXTURE_RESERVE(texture) \
{ \
UserData ud = TEXTURE_USER_DATA(&(texture).texobj); \
GX_InitTexObj(&(texture).texobj, NULL, 0, 0, 0, \
GX_REPEAT, GX_REPEAT, 0); \
UserData ud = { .ptr = NULL }; \
ud.d.is_reserved = 1; \
GX_InitTexObjUserData(&(texture).texobj, ud.ptr); \
}
Expand Down Expand Up @@ -122,6 +124,8 @@ static unsigned char gcgl_texwrap_conv(GLint param)
case GL_MIRRORED_REPEAT:
return GX_MIRROR;
case GL_CLAMP:
case GL_CLAMP_TO_EDGE:
case GL_CLAMP_TO_BORDER:
return GX_CLAMP;
case GL_REPEAT:
default:
Expand Down Expand Up @@ -430,7 +434,6 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
ti.maxlevel = level;
ti.width = wi;
ti.height = he;
ti.wraps = ti.wrapt = GX_REPEAT;
}
if (ti.maxlevel < level)
ti.maxlevel = level;
Expand Down Expand Up @@ -523,7 +526,7 @@ void glDeleteTextures(GLsizei n, const GLuint *textures)
GX_DrawDone();
while (n-- > 0) {
int i = *texlist++;
if (!(i < 0 || i >= _MAX_GL_TEX)) {
if (i > 0 && i < _MAX_GL_TEX) {
void *data = GX_GetTexObjData(&texture_list[i].texobj);
if (data != 0)
free(MEM_PHYSICAL_TO_K0(data));
Expand All @@ -538,8 +541,6 @@ void glGenTextures(GLsizei n, GLuint *textures)
int i;
for (i = 0; i < _MAX_GL_TEX && n > 0; i++) {
if (!TEXTURE_IS_RESERVED(texture_list[i])) {
GXTexObj *texobj = &texture_list[i].texobj;
GX_InitTexObj(texobj, NULL, 0, 0, 0, GX_REPEAT, GX_REPEAT, 0);
TEXTURE_RESERVE(texture_list[i]);
*texlist++ = i;
n--;
Expand Down
Loading