ref: 78f40b98dbd8ceb0e1bae3a88a89ff7919a6bda1
dir: /src/zraster.c/
#include "../include/GL/gl.h"
#include "../include/zbuffer.h"
#include "zgl.h"
#include "msghandling.h"
static inline void gl_vertex_transform_raster(GLVertex* v) {
GLContext* c = gl_get_context();
{
/* no eye coordinates needed, no normal */
/* NOTE: W = 1 is assumed */
GLfloat* m = &c->matrix_model_projection.m[0][0];
v->pc.X = (v->coord.X * m[0] + v->coord.Y * m[1] + v->coord.Z * m[2] + m[3]);
v->pc.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + v->coord.Z * m[6] + m[7]);
v->pc.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + v->coord.Z * m[10] + m[11]);
if (c->matrix_model_projection_no_w_transform) {
v->pc.W = m[15];
} else {
v->pc.W = (v->coord.X * m[12] + v->coord.Y * m[13] + v->coord.Z * m[14] + m[15]);
}
m = &c->matrix_stack_ptr[0]->m[0][0];
v->ec.X = (v->coord.X * m[0] + v->coord.Y * m[1] + v->coord.Z * m[2] + m[3]);
v->ec.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + v->coord.Z * m[6] + m[7]);
v->ec.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + v->coord.Z * m[10] + m[11]);
v->ec.W = (v->coord.X * m[12] + v->coord.Y * m[13] + v->coord.Z * m[14] + m[15]);
}
v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W);
}
void glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w){
GLParam p[5];
p[0].op = OP_RasterPos;
p[1].f = x;
p[2].f = y;
p[3].f = z;
p[4].f = w;
gl_add_op(p);
}
void glopRasterPos(GLParam* p){
GLContext* c = gl_get_context();
GLVertex v;
v.coord.X = p[1].f;
v.coord.Y = p[2].f;
v.coord.Z = p[3].f;
v.coord.W = p[4].f;
gl_vertex_transform_raster(&v);
if (v.clip_code == 0)
{
{
GLfloat winv = 1.0 / v.pc.W;
v.zp.x = (GLint)(v.pc.X * winv * c->viewport.scale.X + c->viewport.trans.X);
v.zp.y = (GLint)(v.pc.Y * winv * c->viewport.scale.Y + c->viewport.trans.Y);
v.zp.z = (GLint)(v.pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z);
}
c->rasterpos.v[0] = v.zp.x;
c->rasterpos.v[1] = v.zp.y;
c->rastervertex = v;
//c->rasterpos.v[2] = v.zp.z;
c->rasterpos_zz = v.zp.z >> ZB_POINT_Z_FRAC_BITS; //I believe this is it?
c->rasterposvalid = 1;
}
else
c->rasterposvalid = 0;
}
void glRasterPos2f(GLfloat x, GLfloat y){glRasterPos4f(x,y,0,1);}
void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z){glRasterPos4f(x,y,z,1);}
void glRasterPos2fv(GLfloat* v){glRasterPos2f(v[0],v[1]);}
void glRasterPos3fv(GLfloat* v){glRasterPos3f(v[0],v[1],v[2]);}
void glRasterPos4fv(GLfloat* v){glRasterPos4f(v[0],v[1],v[2],v[3]);}
void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, void* data){
/* TODO: Come up with a clever scheme for storing the data to avoid pointer dependency. */
#if TGL_FEATURE_RENDER_BITS == 32
if( type != GL_UNSIGNED_INT &&
type != GL_UNSIGNED_INT_8_8_8_8 )
{
tgl_warning("\nERROR: Incorrect type for glDrawPixels. It MUST be GL_UNSIGNED_INT or GL_UNSIGNED_INT_8_8_8_8, A R G B!");
return;
}
#elif TGL_FEATURE_RENDER_BITS == 16
if( type != GL_UNSIGNED_SHORT &&
type != GL_UNSIGNED_SHORT_5_6_5)
{
tgl_warning("\nERROR: Incorrect type for glDrawPixels. it MUST be GL_UNSIGNED_SHORT or GL_UNSIGNED_SHORT_5_6_5, R5 G6 B5!");
return;
}
#else
#error "Bad TGL_FEATURE_RENDER_BITS"
#endif
if( format != GL_RGB ){
tgl_warning("\nERROR: Incorrect format for glDrawPixels.");
return;
}
GLParam p[6];
p[0].op = OP_DrawPixels;
p[1].i = width;
p[2].i = height;
p[3].p = data;
gl_add_op(p);
}
#define ZCMP(z, zpix) (!(zbdt) || z >= (zpix))
#define CLIPTEST(_x,_y,_w,_h)((0<=_x) && (_w>_x) && (0<=_y) && (_h>_y))
void glopDrawPixels(GLParam* p){
GLContext* c = gl_get_context();
// p[3]
if(!c->rasterposvalid) return;
GLint w = p[1].i;
GLint h = p[2].i;
V4 rastpos = c->rasterpos;
ZBuffer* zb = c->zb;
PIXEL* d = p[3].p;
PIXEL* pbuf = zb->pbuf;
GLushort* zbuf = zb->zbuf;
GLubyte zbdw = zb->depth_write;
GLubyte zbdt = zb->depth_test;
GLint tw = zb->xsize;
GLint th = zb->ysize;
GLfloat pzoomx = c->pzoomx;
GLfloat pzoomy = c->pzoomy;
GLint zz = c->rasterpos_zz;
#if TGL_FEATURE_BLEND_DRAW_PIXELS == 1
TGL_BLEND_VARS
#endif
#if TGL_FEATURE_BLEND == 1
#if TGL_FEATURE_BLEND_DRAW_PIXELS == 1
GLuint zbeb = zb->enable_blend;
#endif
#endif
//Looping over the source pixels.
#if TGL_FEATURE_ALT_RENDERMODES == 1
if(c->render_mode == GL_SELECT){
gl_add_select( zz, zz);
return;
} else if(c->render_mode == GL_FEEDBACK){
gl_add_feedback(
GL_DRAW_PIXEL_TOKEN,
&(c->rastervertex),
NULL,
NULL,
0
);
return;
}
#endif
// Works.
#if TGL_FEATURE_MULTITHREADED_DRAWPIXELS == 1
#pragma omp parallel for
for(GLint sy = 0; sy < h; sy++)
for(GLint sx = 0; sx < w; sx++)
{
PIXEL col = d[sy*w+sx];
V4 rastoffset;
rastoffset.v[0] = rastpos.v[0] + (GLfloat)sx * pzoomx;
rastoffset.v[1] = rastpos.v[1] - ((GLfloat)(h-sy) * pzoomy);
rastoffset.v[2] = rastoffset.v[0] + pzoomx;
rastoffset.v[3] = rastoffset.v[1] - pzoomy;
for(GLint ty = rastoffset.v[1]; (GLfloat)ty > rastoffset.v[3];ty--)
for(GLint tx = rastoffset.v[0]; (GLfloat)tx < rastoffset.v[2];tx++)
if(CLIPTEST(tx,ty,tw,th)){
GLushort* pz = zbuf + (ty * tw + tx);
if(ZCMP(zz,*pz)){
#if TGL_FEATURE_BLEND == 1
#if TGL_FEATURE_BLEND_DRAW_PIXELS == 1
if(!zbeb)
pbuf[tx+ty*tw] = col;
else
TGL_BLEND_FUNC(col, pbuf[tx+ty*tw])
#else
pbuf[tx+ty*tw] = col;
#endif
#else
pbuf[tx+ty*tw] = col;
#endif
if(zbdw) *pz = zz;
}
}
}
#else
for(GLint sy = 0; sy < h; sy++)
for(GLint sx = 0; sx < w; sx++)
{
PIXEL col = d[sy*w+sx];
V4 rastoffset;
rastoffset.v[0] = rastpos.v[0] + (GLfloat)sx * pzoomx;
rastoffset.v[1] = rastpos.v[1] - ((GLfloat)(h-sy) * pzoomy);
rastoffset.v[2] = rastoffset.v[0] + pzoomx;
rastoffset.v[3] = rastoffset.v[1] - pzoomy;
for(GLint ty = rastoffset.v[1]; (GLfloat)ty > rastoffset.v[3];ty--)
for(GLint tx = rastoffset.v[0]; (GLfloat)tx < rastoffset.v[2];tx++)
if(CLIPTEST(tx,ty,tw,th)){
GLushort* pz = zbuf + (ty * tw + tx);
if(ZCMP(zz,*pz)){
#if TGL_FEATURE_BLEND == 1
#if TGL_FEATURE_BLEND_DRAW_PIXELS == 1
if(!zbeb)
pbuf[tx+ty*tw] = col;
else
TGL_BLEND_FUNC(col, pbuf[tx+ty*tw])
#else
pbuf[tx+ty*tw] = col;
#endif
#else
pbuf[tx+ty*tw] = col;
#endif
if(zbdw) *pz = zz;
}
}
}
#endif
}
void glPixelZoom(GLfloat x, GLfloat y){
GLParam p[3];
p[0].op = OP_PixelZoom;
p[1].f = x;
p[2].f = y;
gl_add_op(p);
}
void glopPixelZoom(GLParam* p){
GLContext* c = gl_get_context();
c->pzoomx = p[1].f;
c->pzoomy = p[2].f;
}