X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fgles2glide64%2Fsrc%2FGlitch64%2Fgeometry.cpp;fp=source%2Fgles2glide64%2Fsrc%2FGlitch64%2Fgeometry.cpp;h=92e79eb48b26ceac4f48e2fe3aa9bcb4e62d0beb;hb=98e75f2d18c02c233da543560f76282f04fc796c;hp=0000000000000000000000000000000000000000;hpb=0ced54f867d36e8b324155bef49e8abfebfc3237;p=mupen64plus-pandora.git diff --git a/source/gles2glide64/src/Glitch64/geometry.cpp b/source/gles2glide64/src/Glitch64/geometry.cpp new file mode 100755 index 0000000..92e79eb --- /dev/null +++ b/source/gles2glide64/src/Glitch64/geometry.cpp @@ -0,0 +1,658 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#ifdef _WIN32 +#include +#endif // _WIN32 +#include "glide.h" +#include "main.h" +#include "../Glide64/winlnxdefs.h" +#include "../Glide64/rdp.h" + + + +#define Z_MAX (65536.0f) +#define VERTEX_SIZE sizeof(VERTEX) //Size of vertex struct + +#ifdef PAULSCODE +//#include "ae_bridge.h" +static float polygonOffsetFactor; +static float polygonOffsetUnits; +#endif + +static int xy_off; +static int xy_en; +static int z_en; +static int z_off; +static int q_off; +static int q_en; +static int pargb_off; +static int pargb_en; +static int st0_off; +static int st0_en; +static int st1_off; +static int st1_en; +static int fog_ext_off; +static int fog_ext_en; + +int w_buffer_mode; +int inverted_culling; +int culling_mode; + +#define VERTEX_BUFFER_SIZE 1500 //Max amount of vertices to buffer, this seems large enough. +static VERTEX vertex_buffer[VERTEX_BUFFER_SIZE]; +static int vertex_buffer_count = 0; +static GLenum vertex_draw_mode; +static bool vertex_buffer_enabled = false; + +void vbo_init() +{ + +} + +void vbo_draw() +{ + if(vertex_buffer_count) + { + glDrawArrays(vertex_draw_mode,0,vertex_buffer_count); + vertex_buffer_count = 0; + } +} + +#ifdef PAULSCODE +void vbo_resetcount() +{ + vertex_buffer_count = 0; +} +#endif + +//Buffer vertices instead of glDrawArrays(...) +void vbo_buffer(GLenum mode,GLint first,GLsizei count,void* pointers) +{ + if((count != 3 && mode != GL_TRIANGLES) || vertex_buffer_count + count > VERTEX_BUFFER_SIZE) + { + vbo_draw(); + } + + memcpy(&vertex_buffer[vertex_buffer_count],pointers,count * VERTEX_SIZE); + vertex_buffer_count += count; + + if(count == 3 || mode == GL_TRIANGLES) + { + vertex_draw_mode = GL_TRIANGLES; + } + else + { + vertex_draw_mode = mode; + vbo_draw(); //Triangle fans and strips can't be joined as easily, just draw them straight away. + } + + +} + +void vbo_enable() +{ + if(vertex_buffer_enabled) + return; + + vertex_buffer_enabled = true; + glEnableVertexAttribArray(POSITION_ATTR); + glVertexAttribPointer(POSITION_ATTR, 4, GL_FLOAT, false, VERTEX_SIZE, &vertex_buffer[0].x); //Position + + glEnableVertexAttribArray(COLOUR_ATTR); + glVertexAttribPointer(COLOUR_ATTR, 4, GL_UNSIGNED_BYTE, true, VERTEX_SIZE, &vertex_buffer[0].b); //Colour + + glEnableVertexAttribArray(TEXCOORD_0_ATTR); + glVertexAttribPointer(TEXCOORD_0_ATTR, 2, GL_FLOAT, false, VERTEX_SIZE, &vertex_buffer[0].coord[2]); //Tex0 + + glEnableVertexAttribArray(TEXCOORD_1_ATTR); + glVertexAttribPointer(TEXCOORD_1_ATTR, 2, GL_FLOAT, false, VERTEX_SIZE, &vertex_buffer[0].coord[0]); //Tex1 + + glEnableVertexAttribArray(FOG_ATTR); + glVertexAttribPointer(FOG_ATTR, 1, GL_FLOAT, false, VERTEX_SIZE, &vertex_buffer[0].f); //Fog +} + +void vbo_disable() +{ + vbo_draw(); + vertex_buffer_enabled = false; +} + + +inline float ZCALC(const float & z, const float & q) { + float res = z_en ? ((z) / Z_MAX) / (q) : 1.0f; + return res; +} + +/* +#define zclamp (1.0f-1.0f/zscale) +static inline void zclamp_glVertex4f(float a, float b, float c, float d) +{ + if (c 0.01f) continue; + if (z < bestz) { + bestz = z; + biasFactor = f; + } + //printf("f %g z %g\n", f, z); + } + //printf(" --> bias factor %g\n", biasFactor); + glPopAttrib(); +#endif +} + +FX_ENTRY void FX_CALL +grDepthBiasLevel( FxI32 level ) +{ + LOG("grDepthBiasLevel(%d)\r\n", level); + if (level) + { + #ifdef PAULSCODE + glPolygonOffset(polygonOffsetFactor, polygonOffsetUnits); +/* if(w_buffer_mode) + glPolygonOffset(1.0f, -(float)level*polygonOffsetUnits); + else + glPolygonOffset(0, (float)level*3.0f);*/ + #else + if(w_buffer_mode) + glPolygonOffset(1.0f, -(float)level*zscale/255.0f); + else + glPolygonOffset(0, (float)level*biasFactor); + #endif + glEnable(GL_POLYGON_OFFSET_FILL); + } + else + { + glPolygonOffset(0,0); + glDisable(GL_POLYGON_OFFSET_FILL); + } +} + +// draw + +FX_ENTRY void FX_CALL +grDrawTriangle( const void *a, const void *b, const void *c ) +{ + LOG("grDrawTriangle()\r\n\t"); +/* + if(nvidia_viewport_hack && !render_to_texture) + { + glViewport(0, viewport_offset, viewport_width, viewport_height); + nvidia_viewport_hack = 0; + } +*/ + reloadTexture(); + + if(need_to_compile) compile_shader(); + + if(vertex_buffer_count + 3 > VERTEX_BUFFER_SIZE) + { + vbo_draw(); + } + vertex_draw_mode = GL_TRIANGLES; + memcpy(&vertex_buffer[vertex_buffer_count],a,VERTEX_SIZE); + memcpy(&vertex_buffer[vertex_buffer_count+1],b,VERTEX_SIZE); + memcpy(&vertex_buffer[vertex_buffer_count+2],c,VERTEX_SIZE); + vertex_buffer_count += 3; +} + +FX_ENTRY void FX_CALL +grDrawPoint( const void *pt ) +{ +/* + float *x = (float*)pt + xy_off/sizeof(float); + float *y = (float*)pt + xy_off/sizeof(float) + 1; + float *z = (float*)pt + z_off/sizeof(float); + float *q = (float*)pt + q_off/sizeof(float); + unsigned char *pargb = (unsigned char*)pt + pargb_off; + float *s0 = (float*)pt + st0_off/sizeof(float); + float *t0 = (float*)pt + st0_off/sizeof(float) + 1; + float *s1 = (float*)pt + st1_off/sizeof(float); + float *t1 = (float*)pt + st1_off/sizeof(float) + 1; + float *fog = (float*)pt + fog_ext_off/sizeof(float); + LOG("grDrawPoint()\r\n"); + + if(nvidia_viewport_hack && !render_to_texture) + { + glViewport(0, viewport_offset, viewport_width, viewport_height); + nvidia_viewport_hack = 0; + } + + reloadTexture(); + + if(need_to_compile) compile_shader(); + + glBegin(GL_POINTS); + + if (nbTextureUnits > 2) + { + if (st0_en) + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *s0 / *q / (float)tex1_width, + ytex(0, *t0 / *q / (float)tex1_height)); + if (st1_en) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *s1 / *q / (float)tex0_width, + ytex(1, *t1 / *q / (float)tex0_height)); + } + else + { + if (st0_en) + glTexCoord2f(*s0 / *q / (float)tex0_width, + ytex(0, *t0 / *q / (float)tex0_height)); + } + if (pargb_en) + glColor4f(pargb[2]/255.0f, pargb[1]/255.0f, pargb[0]/255.0f, pargb[3]/255.0f); + if (fog_enabled && fog_coord_support) + { + if(!fog_ext_en || fog_enabled != 2) + glSecondaryColor3f((1.0f / *q) / 255.0f, 0.0f, 0.0f); + else + glSecondaryColor3f((1.0f / *fog) / 255.0f, 0.0f, 0.0f); + } + glVertex4f((*x - (float)widtho) / (float)(width/2) / *q, + -(*y - (float)heighto) / (float)(height/2) / *q, ZCALC(*z ,*q), 1.0f / *q); + + glEnd(); +*/ +} + +FX_ENTRY void FX_CALL +grDrawLine( const void *a, const void *b ) +{ +/* + float *a_x = (float*)a + xy_off/sizeof(float); + float *a_y = (float*)a + xy_off/sizeof(float) + 1; + float *a_z = (float*)a + z_off/sizeof(float); + float *a_q = (float*)a + q_off/sizeof(float); + unsigned char *a_pargb = (unsigned char*)a + pargb_off; + float *a_s0 = (float*)a + st0_off/sizeof(float); + float *a_t0 = (float*)a + st0_off/sizeof(float) + 1; + float *a_s1 = (float*)a + st1_off/sizeof(float); + float *a_t1 = (float*)a + st1_off/sizeof(float) + 1; + float *a_fog = (float*)a + fog_ext_off/sizeof(float); + + float *b_x = (float*)b + xy_off/sizeof(float); + float *b_y = (float*)b + xy_off/sizeof(float) + 1; + float *b_z = (float*)b + z_off/sizeof(float); + float *b_q = (float*)b + q_off/sizeof(float); + unsigned char *b_pargb = (unsigned char*)b + pargb_off; + float *b_s0 = (float*)b + st0_off/sizeof(float); + float *b_t0 = (float*)b + st0_off/sizeof(float) + 1; + float *b_s1 = (float*)b + st1_off/sizeof(float); + float *b_t1 = (float*)b + st1_off/sizeof(float) + 1; + float *b_fog = (float*)b + fog_ext_off/sizeof(float); + LOG("grDrawLine()\r\n"); + + if(nvidia_viewport_hack && !render_to_texture) + { + glViewport(0, viewport_offset, viewport_width, viewport_height); + nvidia_viewport_hack = 0; + } + + reloadTexture(); + + if(need_to_compile) compile_shader(); + + glBegin(GL_LINES); + + if (nbTextureUnits > 2) + { + if (st0_en) + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *a_s0 / *a_q / (float)tex1_width, ytex(0, *a_t0 / *a_q / (float)tex1_height)); + if (st1_en) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *a_s1 / *a_q / (float)tex0_width, ytex(1, *a_t1 / *a_q / (float)tex0_height)); + } + else + { + if (st0_en) + glTexCoord2f(*a_s0 / *a_q / (float)tex0_width, ytex(0, *a_t0 / *a_q / (float)tex0_height)); + } + if (pargb_en) + glColor4f(a_pargb[2]/255.0f, a_pargb[1]/255.0f, a_pargb[0]/255.0f, a_pargb[3]/255.0f); + if (fog_enabled && fog_coord_support) + { + if(!fog_ext_en || fog_enabled != 2) + glSecondaryColor3f((1.0f / *a_q) / 255.0f, 0.0f, 0.0f); + else + glSecondaryColor3f((1.0f / *a_fog) / 255.0f, 0.0f, 0.0f); + } + glVertex4f((*a_x - (float)widtho) / (float)(width/2) / *a_q, + -(*a_y - (float)heighto) / (float)(height/2) / *a_q, ZCALC(*a_z, *a_q), 1.0f / *a_q); + + if (nbTextureUnits > 2) + { + if (st0_en) + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, *b_s0 / *b_q / (float)tex1_width, + ytex(0, *b_t0 / *b_q / (float)tex1_height)); + if (st1_en) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, *b_s1 / *b_q / (float)tex0_width, + ytex(1, *b_t1 / *b_q / (float)tex0_height)); + } + else + { + if (st0_en) + glTexCoord2f(*b_s0 / *b_q / (float)tex0_width, + ytex(0, *b_t0 / *b_q / (float)tex0_height)); + } + if (pargb_en) + glColor4f(b_pargb[2]/255.0f, b_pargb[1]/255.0f, b_pargb[0]/255.0f, b_pargb[3]/255.0f); + if (fog_enabled && fog_coord_support) + { + if(!fog_ext_en || fog_enabled != 2) + glSecondaryColor3f((1.0f / *b_q) / 255.0f, 0.0f, 0.0f); + else + glSecondaryColor3f((1.0f / *b_fog) / 255.0f, 0.0f, 0.0f); + } + glVertex4f((*b_x - (float)widtho) / (float)(width/2) / *b_q, + -(*b_y - (float)heighto) / (float)(height/2) / *b_q, ZCALC(*b_z, *b_q), 1.0f / *b_q); + + glEnd(); +*/ +} + +FX_ENTRY void FX_CALL +grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers2) +{ + void **pointers = (void**)pointers2; + LOG("grDrawVertexArray(%d,%d)\r\n", mode, Count); +/* + if(nvidia_viewport_hack && !render_to_texture) + { + glViewport(0, viewport_offset, viewport_width, viewport_height); + nvidia_viewport_hack = 0; + } +*/ + reloadTexture(); + + if(need_to_compile) compile_shader(); + + if(mode != GR_TRIANGLE_FAN) + { + display_warning("grDrawVertexArray : unknown mode : %x", mode); + } + + vbo_enable(); + vbo_buffer(GL_TRIANGLE_FAN,0,Count,pointers[0]); +} + +FX_ENTRY void FX_CALL +grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride) +{ + LOG("grDrawVertexArrayContiguous(%d,%d,%d)\r\n", mode, Count, stride); +/* + if(nvidia_viewport_hack && !render_to_texture) + { + glViewport(0, viewport_offset, viewport_width, viewport_height); + nvidia_viewport_hack = 0; + } +*/ + if(stride != 156) + { + LOGINFO("Incompatible stride\n"); + } + + reloadTexture(); + + if(need_to_compile) compile_shader(); + + vbo_enable(); + + switch(mode) + { + case GR_TRIANGLE_STRIP: + vbo_buffer(GL_TRIANGLE_STRIP,0,Count,pointers); + break; + case GR_TRIANGLE_FAN: + vbo_buffer(GL_TRIANGLE_FAN,0,Count,pointers); + break; + default: + display_warning("grDrawVertexArrayContiguous : unknown mode : %x", mode); + } +}