Character.cpp (pymol-v2.1.0.tar.bz2) | : | Character.cpp (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
skipping to change at line 30 | skipping to change at line 30 | |||
#include"Base.h" | #include"Base.h" | |||
#include"Character.h" | #include"Character.h" | |||
#include"Pixmap.h" | #include"Pixmap.h" | |||
#include"Util.h" | #include"Util.h" | |||
#include"MemoryDebug.h" | #include"MemoryDebug.h" | |||
#include"OOMac.h" | #include"OOMac.h" | |||
#include"Vector.h" | #include"Vector.h" | |||
#include"Text.h" | #include"Text.h" | |||
#include"Texture.h" | #include"Texture.h" | |||
#include"CGO.h" | #include"CGO.h" | |||
#include <glm/gtc/type_ptr.hpp> | ||||
#define HASH_MASK 0x2FFF | #define HASH_MASK 0x2FFF | |||
static unsigned int get_hash(CharFngrprnt * fprnt) | static unsigned int get_hash(CharFngrprnt * fprnt) | |||
{ | { | |||
unsigned int result = 0; | unsigned int result = 0; | |||
unsigned short int *data = fprnt->u.d.data; | unsigned short int *data = fprnt->u.d.data; | |||
result = (data[0] << 1) + data[1]; | result = (data[0] << 1) + data[1]; | |||
result = ((result << 4) + data[2]); | result = ((result << 4) + data[2]); | |||
result = ((result << 7) + data[3]) + (result >> 16); | result = ((result << 7) + data[3]) + (result >> 16); | |||
skipping to change at line 206 | skipping to change at line 207 | |||
float CharacterGetAdvance(PyMOLGlobals * G, int sampling, int id) | float CharacterGetAdvance(PyMOLGlobals * G, int sampling, int id) | |||
{ | { | |||
CCharacter *I = G->Character; | CCharacter *I = G->Character; | |||
CharRec *rec = I->Char + id; | CharRec *rec = I->Char + id; | |||
return rec->Advance / sampling; | return rec->Advance / sampling; | |||
} | } | |||
void CharacterRenderOpenGLPrime(PyMOLGlobals * G, RenderInfo * info) | void CharacterRenderOpenGLPrime(PyMOLGlobals * G, RenderInfo * info) | |||
{ | { | |||
if(G->HaveGUI && G->ValidContext) { | if(G->HaveGUI && G->ValidContext) { | |||
short use_shader; | if ((info && !info->use_shaders) || (!info && !SettingGetGlobal_b(G, cSettin | |||
use_shader = (short) SettingGetGlobal_b(G, cSetting_use_shaders); | g_use_shaders))){ | |||
if (!use_shader){ | ||||
glEnable(GL_TEXTURE_2D); | glEnable(GL_TEXTURE_2D); | |||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |||
} | } | |||
/* glEnable(GL_BLEND); | /* glEnable(GL_BLEND); | |||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); */ | glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); */ | |||
} | } | |||
} | } | |||
void CharacterRenderOpenGLDone(PyMOLGlobals * G, RenderInfo * info) | void CharacterRenderOpenGLDone(PyMOLGlobals * G, RenderInfo * info) | |||
{ | { | |||
if(G->HaveGUI && G->ValidContext) { | if(G->HaveGUI && G->ValidContext) { | |||
short use_shader; | if ((info && !info->use_shaders) || (!info && !SettingGetGlobal_b(G, cSettin | |||
use_shader = (short) SettingGetGlobal_b(G, cSetting_use_shaders); | g_use_shaders))){ | |||
if (!use_shader){ | ||||
glDisable(GL_TEXTURE_2D); | glDisable(GL_TEXTURE_2D); | |||
} | } | |||
/* glDisable(GL_BLEND); */ | /* glDisable(GL_BLEND); */ | |||
} | } | |||
} | } | |||
void CharacterRenderOpenGL(PyMOLGlobals * G, RenderInfo * info, int id, short is worldlabel SHADERCGOARG) | short CharacterRenderOpenGL(PyMOLGlobals * G, RenderInfo * info, int id, short i sworldlabel, short relativeMode SHADERCGOARG) | |||
/* need orientation matrix */ | /* need orientation matrix */ | |||
{ | { | |||
CCharacter *I = G->Character; | CCharacter *I = G->Character; | |||
CharRec *rec = I->Char + id; | CharRec *rec = I->Char + id; | |||
short success = 1; | ||||
int texture_id = TextureGetFromChar(G, id, rec->extent); | int texture_id = TextureGetFromChar(G, id, rec->extent); | |||
float sampling = 1.0F; | float sampling = 1.0F; | |||
if(G->HaveGUI && G->ValidContext && texture_id) { | if(G->HaveGUI && G->ValidContext && texture_id) { | |||
if(info) | if(info) | |||
sampling = (float) info->sampling; | sampling = (float) info->sampling; | |||
if(texture_id) { | if(texture_id) { | |||
/* if(glIsTexture(texture_id)) -- BAD -- impacts performance */ | /* if(glIsTexture(texture_id)) -- BAD -- impacts performance */ | |||
float *v, v0[3]; | float *v, v0[3]; | |||
float v1[3]; | float v1[3]; | |||
if (!shaderCGO){ | if (!shaderCGO){ | |||
glBindTexture(GL_TEXTURE_2D, texture_id); | glBindTexture(GL_TEXTURE_2D, TextGetIsPicking(G) ? 0 : texture_id); | |||
} | } | |||
v = TextGetPos(G); | v = TextGetPos(G); | |||
copy3f(v, v0); | copy3f(v, v0); | |||
v0[0] -= rec->XOrig / sampling; | v0[0] -= rec->XOrig / sampling; | |||
v0[1] -= rec->YOrig / sampling; | v0[1] -= rec->YOrig / sampling; | |||
copy3f(v0, v1); | copy3f(v0, v1); | |||
v1[0] += rec->Width / sampling; | v1[0] += rec->Width / sampling; | |||
v1[1] += rec->Height / sampling; | v1[1] += rec->Height / sampling; | |||
/* glColor4f(0.5F,0.5F,0.5F,1.0F); */ | /* glColor4f(0.5F,0.5F,0.5F,1.0F); */ | |||
if (shaderCGO){ | if (shaderCGO){ | |||
float *worldPos = TextGetWorldPos(G); | float *worldPos = TextGetWorldPos(G); | |||
if (isworldlabel){ | if (isworldlabel){ | |||
float *targetPos = TextGetTargetPos(G); | ||||
float *screenWorldOffset = TextGetScreenWorldOffset(G); | float *screenWorldOffset = TextGetScreenWorldOffset(G); | |||
CGODrawLabel(shaderCGO, texture_id, worldPos, screenWorldOffset, v0, | shaderCGO->add<cgo::draw::label>(glm::make_vec3(worldPos), | |||
v1, rec->extent); | glm::make_vec3(screenWorldOffset), | |||
glm::make_vec3(v0), | ||||
glm::make_vec3(v1), | ||||
glm::make_vec4(rec->extent), | ||||
relativeMode, | ||||
glm::make_vec3(targetPos)); | ||||
} else { | } else { | |||
CGODrawTexture(shaderCGO, texture_id, worldPos, v0, v1, rec->extent); | CGODrawTexture(shaderCGO, texture_id, worldPos, v0, v1, rec->extent); | |||
} | } | |||
} else { | } else { | |||
#ifndef PURE_OPENGL_ES_2 | #ifndef PURE_OPENGL_ES_2 | |||
glBegin(GL_QUADS); | glBegin(GL_QUADS); | |||
if (TextGetIsPicking(G)){ | ||||
unsigned char *cptr = TextGetColorUChar4uv(G); | ||||
glColor4ubv(cptr); | ||||
glVertex3f(v0[0], v0[1], v0[2]); | ||||
glVertex3f(v0[0], v1[1], v0[2]); | ||||
glVertex3f(v1[0], v1[1], v0[2]); | ||||
glVertex3f(v1[0], v0[1], v0[2]); | ||||
glEnd(); | ||||
} else { | ||||
glTexCoord2f(rec->extent[0], rec->extent[1]); | glTexCoord2f(rec->extent[0], rec->extent[1]); | |||
glVertex3f(v0[0], v0[1], v0[2]); | glVertex3f(v0[0], v0[1], v0[2]); | |||
glTexCoord2f(rec->extent[0], rec->extent[3]); | glTexCoord2f(rec->extent[0], rec->extent[3]); | |||
glVertex3f(v0[0], v1[1], v0[2]); | glVertex3f(v0[0], v1[1], v0[2]); | |||
glTexCoord2f(rec->extent[2], rec->extent[3]); | glTexCoord2f(rec->extent[2], rec->extent[3]); | |||
glVertex3f(v1[0], v1[1], v0[2]); | glVertex3f(v1[0], v1[1], v0[2]); | |||
glTexCoord2f(rec->extent[2], rec->extent[1]); | glTexCoord2f(rec->extent[2], rec->extent[1]); | |||
glVertex3f(v1[0], v0[1], v0[2]); | glVertex3f(v1[0], v0[1], v0[2]); | |||
glEnd(); | glEnd(); | |||
} | ||||
#endif | #endif | |||
} | } | |||
} | } | |||
TextAdvance(G, rec->Advance / sampling); | TextAdvance(G, rec->Advance / sampling); | |||
} else { | ||||
if (!texture_id) | ||||
success = 0; | ||||
} | } | |||
return success; | ||||
} | } | |||
int CharacterGetWidth(PyMOLGlobals * G, int id) | int CharacterGetWidth(PyMOLGlobals * G, int id) | |||
{ | { | |||
CCharacter *I = G->Character; | CCharacter *I = G->Character; | |||
if((id > 0) && (id <= I->MaxAlloc)) { | if((id > 0) && (id <= I->MaxAlloc)) { | |||
return I->Char[id].Width; | return I->Char[id].Width; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
const float _inv255 = 1.0F / 255.0F; | const float _inv255 = 1.0F / 255.0F; | |||
const unsigned char zerouc[4] = { 0, 0, 0, 0 }; | ||||
/* CharacterInterpolate: This function implements bilinear interpolation | ||||
on looking up the pixel value in the texture. | ||||
*/ | ||||
float CharacterInterpolate(PyMOLGlobals * G, int id, float *v) | float CharacterInterpolate(PyMOLGlobals * G, int id, float *v) | |||
{ | { | |||
CCharacter *I = G->Character; | CCharacter *I = G->Character; | |||
int x = (int) v[0]; | int x = (int) v[0]; | |||
int y = (int) v[1]; | int y = (int) v[1]; | |||
unsigned char *src; | ||||
if((id > 0) && (id <= I->MaxAlloc)) { | if((id > 0) && (id <= I->MaxAlloc)) { | |||
CPixmap *pm = &I->Char[id].Pixmap; | CPixmap *pm = &I->Char[id].Pixmap; | |||
if(pm) { | if(pm) { | |||
unsigned char *srcx0, *srcx1, *srcy0, *srcy1; | ||||
if(x < 0) | int x1 = x + 1, y1 = y + 1; | |||
x = 0; | float xdiff = v[0] - x, ydiff = v[1] - y; | |||
else if(x >= pm->width) | float xdiff1 = (1.f-xdiff), ydiff1 = (1.f-ydiff); | |||
x = pm->width - 1; /* clamp */ | float interp0[4], interp1[4]; // interpolated in x for y0 and y1 | |||
if(y < 0) | ||||
y = 0; | if (x < 0 || x > (pm->width - 1)) | |||
else if(y >= pm->height) | srcx0 = (unsigned char *)zerouc; | |||
y = pm->height - 1; | else | |||
srcx0 = pm->buffer + ((pm->width << 2) * y) + (x << 2); | ||||
src = pm->buffer + ((pm->width << 2) * y) + (x << 2); | if (x1 < 0 || x1 > (pm->width - 1)) | |||
v[0] = *(src++) * _inv255; | srcx1 = (unsigned char *)zerouc; | |||
v[1] = *(src++) * _inv255; | else | |||
v[2] = *(src++) * _inv255; | srcx1 = pm->buffer + ((pm->width << 2) * y) + (x1 << 2); | |||
return (255 - *(src++)) * _inv255; | ||||
if (y1 < 0 || y1 > (pm->height - 1)) | ||||
srcy0 = (unsigned char *)zerouc; | ||||
else | ||||
srcy0 = pm->buffer + ((pm->width << 2) * y1) + (x << 2); | ||||
if (x1 < 0 || x1 > (pm->width - 1) || y1 < 0 || y1 > (pm->height - 1)) | ||||
srcy1 = (unsigned char *)zerouc; | ||||
else | ||||
srcy1 = pm->buffer + ((pm->width << 2) * y1) + (x1 << 2); | ||||
interp0[0] = (xdiff1 * (*(srcx0++)) + (xdiff * (*(srcx1++)))); | ||||
interp0[1] = (xdiff1 * (*(srcx0++)) + (xdiff * (*(srcx1++)))); | ||||
interp0[2] = (xdiff1 * (*(srcx0++)) + (xdiff * (*(srcx1++)))); | ||||
interp0[3] = (xdiff1 * (*(srcx0++)) + (xdiff * (*(srcx1++)))); | ||||
interp1[0] = (xdiff1 * (*(srcy0++)) + (xdiff * (*(srcy1++)))); | ||||
interp1[1] = (xdiff1 * (*(srcy0++)) + (xdiff * (*(srcy1++)))); | ||||
interp1[2] = (xdiff1 * (*(srcy0++)) + (xdiff * (*(srcy1++)))); | ||||
interp1[3] = (xdiff1 * (*(srcy0++)) + (xdiff * (*(srcy1++)))); | ||||
v[0] = ((ydiff1 * interp0[0]) + (ydiff * interp1[0])) * _inv255; | ||||
v[1] = ((ydiff1 * interp0[1]) + (ydiff * interp1[1])) * _inv255; | ||||
v[2] = ((ydiff1 * interp0[2]) + (ydiff * interp1[2])) * _inv255; | ||||
return (255 - ((ydiff1 * interp0[3]) + (ydiff * interp1[3]))) * _inv255; | ||||
} else { | } else { | |||
zero3f(v); | zero3f(v); | |||
return 1.0F; | return 1.0F; | |||
} | } | |||
} | } | |||
zero3f(v); | ||||
return 1.0F; | return 1.0F; | |||
} | } | |||
int CharacterGetHeight(PyMOLGlobals * G, int id) | int CharacterGetHeight(PyMOLGlobals * G, int id) | |||
{ | { | |||
CCharacter *I = G->Character; | CCharacter *I = G->Character; | |||
if((id > 0) && (id <= I->MaxAlloc)) { | if((id > 0) && (id <= I->MaxAlloc)) { | |||
return I->Char[id].Height; | return I->Char[id].Height; | |||
} | } | |||
return 0; | return 0; | |||
End of changes. 16 change blocks. | ||||
27 lines changed or deleted | 75 lines changed or added |