Альтернативный способ, если вы не хотите поднимать ошибки, если один из ключей отсутствует (чтобы ваш основной код мог работать без прерывания):
def get_value(self,your_dict,*keys):
curr_dict_ = your_dict
for k in keys:
v = curr_dict.get(k,None)
if v is None:
break
if isinstance(v,dict):
curr_dict = v
return v
В этом случае, если есть входных ключей нет, возвращается None, которое может использоваться как проверка вашего основного кода для выполнения альтернативной задачи.
Как я уже упоминал в своем комментарии, у Intel OpenGL-драйверов есть проблемы с прямым рендерингом текстуры, и я не знаю ни одного обходного пути, которое работает. В этом случае единственный способ обойти это - glReadPixels
, чтобы скопировать содержимое экрана в память ЦП, а затем скопировать его на GPU в виде текстуры. Грубый, который намного медленнее, чем прямой рендеринг текстуры. Итак, вот сделка:
glViewport
. Затем визуализируйте свою сцену в низком разрешении (всего лишь на части экрана). GL_NEAREST
. Самое главное, что вы меняете буферы только после этого не раньше !!! в противном случае вы бы мерцали. Здесь источник C ++ для этого:
void gl_draw()
{
// render resolution and multiplier
const int xs=320,ys=200,m=2;
// [low res render pass]
glViewport(0,0,xs,ys);
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// 50 random lines
RandSeed=0x12345678;
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINES);
for (int i=0;i<100;i++)
glVertex2f(2.0*Random()-1.0,2.0*Random()-1.0);
glEnd();
// [multiply resiolution render pass]
static bool _init=true;
GLuint txrid=0; // texture id
BYTE map[xs*ys*3]; // RGB
// init texture
if (_init) // you should also delte the texture on exit of app ...
{
// create texture
_init=false;
glGenTextures(1,&txrid);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txrid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST); // must be nearest !!!
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_COPY);
glDisable(GL_TEXTURE_2D);
}
// copy low res screen to CPU memory
glReadPixels(0,0,xs,ys,GL_RGB,GL_UNSIGNED_BYTE,map);
// and then to GPU texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txrid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, xs, ys, 0, GL_RGB, GL_UNSIGNED_BYTE, map);
// set multiplied resolution view
glViewport(0,0,m*xs,m*ys);
glClear(GL_COLOR_BUFFER_BIT);
// render low res screen as texture
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0); glVertex2f(-1.0,-1.0);
glTexCoord2f(0.0,1.0); glVertex2f(-1.0,+1.0);
glTexCoord2f(1.0,1.0); glVertex2f(+1.0,+1.0);
glTexCoord2f(1.0,0.0); glVertex2f(+1.0,-1.0);
glEnd();
glDisable(GL_TEXTURE_2D);
glFlush();
SwapBuffers(hdc); // swap buffers only here !!!
}
И предварительный просмотр:
Я тестировал это на некоторых графиках Intel HD (бог знает, какая версия) я получил в своем распоряжении, и он работает (в то время как стандартные визуализации для подходов к тексту не являются).
Нет «320x240 glOrtho canvas». Фактическое разрешение окна: 960x720.
Все, что вы делаете, - это увеличение координат примитивов, которые вы визуализируете. Таким образом, ваш код говорит, чтобы сделать линию от, например, (20, 20) до (40, 40). И OpenGL (в конечном счете) масштабирует эти координаты на 3 в каждом измерении: (60, 60) и (120x120).
Но это касается только конечных точек . То, что происходит посередине, по-прежнему основывается на том факте, что вы выполняете рендеринг в фактическом разрешении окна.
Даже если вы использовали glLineWidth
для изменения ширины ваших линий, это только исправило бы линию ширина. Это не повлияет на то, что растрирование линий основано на фактическом разрешении, которое вы выполняете. Таким образом, диагональные линии не будут иметь пикселированный вид, который вы, вероятно, захотите.
Единственный способ сделать это правильно - это правильно сделать это. Отобразите изображение, которое является фактическим 320x240, затем примените его к фактическому разрешению окна.
Вам нужно будет создать текстуру этого размера, а затем привязать его к объекту framebuffer . Привяжите FBO для рендеринга и рендеринга к нему (при этом размер окна просмотра установлен на размер изображения). Затем отвяжите FBO и нарисуйте эту текстуру в окне (с учетом окна просмотра).
glReadPixels
...
– Spektre
26 April 2017 в 08:27