/* 1) Отрисовать что-либо при помощи Win GDI */
DrawPreGL();
/* 2) Отрисовать что-либо при помощи OpenGL */
DrawOGL();
/* 3) Отрисовать что-либо при помощи Win GDI */
DrawPostGL();
SwapBuffers();
т.е. отрисовать до и после OpenGL при двойной буфферизации. Шаги 2 и 3 выполняются при этом хорошо, а вот шаг 1 совсем "забывается" после SwapBuffers, т.к. WinGDI рисует на front buffer.
Спасибо за ответ,
S>1. это плохая идея, не стоит так делать
А какая идея будет получше, если хочется повыводить достаточно простыми методами с достаточным уровнем предсказуемости результатов двумерную графику совместно с трёхмерной. Хотябы текст как надо порисовать. У меня проект — кад и в в нём "маст би" много подписей-надписей-графики под и поверх 3D. Я не очень силён в OGL, потому может просто не знаю боль-мень дешевого пути.
Здравствуйте LtS, Вы писали:
LtS> Спасибо за ответ,
S>>1. это плохая идея, не стоит так делать LtS> А какая идея будет получше, если хочется повыводить достаточно простыми методами с достаточным уровнем предсказуемости результатов двумерную графику совместно с трёхмерной.
ПОнятно. У OpenGL точнее его куска под Windows есть чудесная функция wglBuildFontBitmaps.
Она по выбраному на данный момент в DC шрифту строит растровые изображения и кидает их в displayList-ы.
Потом ими можно очень просто выводить текст.
Вот привожу класс обертку для писания шрифтом в OpenGL
GLFont.h
// GLFont.h: interface for the CGLFont class.
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_)
#define AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif// _MSC_VER > 1000#include <gl\gl.h>
#include <stdarg.h>
#include"vector.hpp"class CGLFont
{
public:
bool Print(const dvector dvPos, const char *fmt, ...);
CSize GetTextSize(LPCTSTR pText);
bool VerifyContext();
bool Create(TCHAR* szFaceName = "Arial", int iHeight = -12, bool bBold=false, bool bItalic=false);
bool KillFont();
CGLFont();
virtual ~CGLFont();
private:
HGLRC m_hNativeGLRC; // Holds HGLRC in which the font has been created
HDC m_hNativeDC; // Holds HGLRC in which the font has been createdbool m_bFontCreated;
GLuint m_uiBase;
HFONT m_hFont;
};
#endif// !defined(AFX_GLFONT_H__563EFF12_A150_47EB_86C1_6F1E2B420978__INCLUDED_)
// GLFont.cpp: implementation of the CGLFont class.
//
// Purpose: OpenGL raster font wrapper
// Author: Alexander Bijamov aka Sasparella
// Created: N/A
//
// Last Modified: 10 April 2002 by A. Bijamov.
//
//////////////////////////////////////////////////////////////////////#include"stdafx.h"#include"GLFont.h"#include"OpenGL.h"#include"routines.h"#include <gl\gl.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////#define NUM_CHARACTERS 96
CGLFont::CGLFont()
{
m_hNativeGLRC = NULL;
m_hNativeDC = NULL;
m_bFontCreated = false;
m_hFont = NULL;
}
CGLFont::~CGLFont()
{
KillFont();
}
bool CGLFont::Create(TCHAR *szFaceName, int iHeight, bool bBold, bool bItalic)
{
if (m_bFontCreated && (!KillFont())) return false; // could not kill font - probably different context
HDC hDC = ::wglGetCurrentDC();
if (!hDC) return false;
m_hFont = CreateFont(iHeight,
0, // Width Of Font
0, // Angle Of Escapement
0, // Orientation Angle
bBold? FW_BOLD:FW_NORMAL, // Font Weight
bItalic, // Italic
FALSE, // Underline
FALSE, // Strikeout
ANSI_CHARSET, // Character Set Identifier
OUT_TT_PRECIS, // Output Precision
CLIP_DEFAULT_PRECIS, // Clipping Precision
ANTIALIASED_QUALITY, // Output Quality
FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch
szFaceName); // Font Nameif (!m_hFont)
{
DisplayErrorMessage("CreateFont");
return false;
}
m_uiBase = glGenLists(NUM_CHARACTERS);
HFONT hOldFnt = (HFONT)SelectObject(hDC, (HGDIOBJ)m_hFont); // Selects The Font We Want
VERIFY(wglUseFontBitmaps(hDC, 32, NUM_CHARACTERS, m_uiBase)); // Builds 96 Characters Starting At Character 32
glFlush();
SelectObject(hDC, (HGDIOBJ)hOldFnt);
m_hNativeGLRC = :: wglGetCurrentContext();
m_hNativeDC = hDC;
m_bFontCreated = true;
return true;
}
bool CGLFont::KillFont()
{
//if (!VerifyContext()) return false; // you try to kill font, but you did not create it...if (!m_bFontCreated) return false;
CToggleContext tc(m_hNativeDC, m_hNativeGLRC);
ASSERT(::wglGetCurrentContext());
glDeleteLists(m_uiBase, NUM_CHARACTERS);
DeleteObject(m_hFont);
m_bFontCreated = false;
return true;
}
bool CGLFont::VerifyContext()
{
return (m_bFontCreated && ::wglGetCurrentContext()==m_hNativeGLRC && ::wglGetCurrentDC()==m_hNativeDC );
}
CSize CGLFont::GetTextSize(LPCTSTR pText)
{
if (!m_bFontCreated) return CSize(0,0);
HFONT hOldFnt = (HFONT)SelectObject(m_hNativeDC, (HGDIOBJ)m_hFont);
CDC* pDC = CDC::FromHandle(m_hNativeDC);
CSize size = pDC->GetTextExtent(CString(pText));
SelectObject(m_hNativeDC, (HGDIOBJ)hOldFnt);
return size;
}
bool CGLFont::Print(const dvector dvPos, const char *fmt, ...)
{
if (!VerifyContext()) return false;
char text[256];
va_list ap;
if (fmt == NULL)
return true;
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
glRasterPos3d(dvPos.x,dvPos.y,dvPos.z);
glPushAttrib(GL_LIST_BIT);
glListBase(m_uiBase - 32);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
return true;
}
...ну тогда ещё один навера последний вопрос: как толком рисовать в OGL не разбираясь с 3D?
Наверна надо будет сказать glDisable(GL_DEPTH_TEST), для начала. А потом хотелось бы, чтобы во всех проекциях например нарисовалась линия из (0,0) в (100, 100). Вообще говоря настройка матриц — не самый плохой вариант, но может есть что-то более прогрессивное и главное простое?
Здравствуйте LtS, Вы писали:
LtS>Большое спасибо! &
LtS>...ну тогда ещё один навера последний вопрос: как толком рисовать в OGL не разбираясь с 3D?
LtS>Наверна надо будет сказать glDisable(GL_DEPTH_TEST), для начала. А потом хотелось бы, чтобы во всех проекциях например нарисовалась линия из (0,0) в (100, 100). Вообще говоря настройка матриц — не самый плохой вариант, но может есть что-то более прогрессивное и главное простое?
Ну куда уж прогрессивнее и проще, чем пару матриц настроитть!
Ок, без проблем. Можно настроить матрицы преобразования так, чтобы рисовать прямо в "оконных" координатах. Конкретно:
Here is code to configure OpenGL for a 2D window coordinate system with an upper left-hand origin where w and h are the windowâs width and height in pixels:
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Note that the bottom and top parameters (the 3rd and 4th parameters) to glOrtho specify the window height as the top and zero as the bottom. This flips the origin to put the origin at the windowâs upper left-hand corner.
Now, you can safely set the raster position at a pixel position in window coordinates like this
glVertex2i(x, y);
glRasterPos2i(x, y);
Стаься во многих смыслах полезная, и избавляющая от многих часов битья головой об стену...
А OpenGL между прочим содержит ф-ии типа glVertex2d — то есть 2d — это его частный случай. Но все равно настраивать нужно как для 3д, — просто как будто сверху смотрим на лист фанеры....
...пасибки! Частично перевёл код на OGL. Головой обычно я правда не бьюсь — это для любителей искуства всё же. Обычно на такое не хватает времени. Сейчас начал прилизывать проектец и вот началось всякое...
...итак, последнее что осталось от Win GDI это вывод текста. Как и следовало предполагать указанный способ не позволяет выводить текст под каким-либо углом кроме простого горизонтального положения.
Нет. не совсем. Дел в том, что матрицы преобразований действую на позицию вывода растра, соответствующего букве, а не на сам растр.
Я не пробовал писать повернутым шрифтом, но могу сфолрмулироват ьнесколько фактов, возмжно могущим вам помоч.
1. Такой фокус точно пройдет c wglFontOutlines, но испольнозать их дорого.
2. Текст пишется, (а не происходит вывод букв друг на друге) так как вывод Bitmap-а сдвигает текущую позиуию растра. По умолчанию — вправо на свой размер. Этим кажется можно управлять — и заставить его смещать его вниз. Тогда текст будет писаться вертикально.
3. Повернутые буквы можно получить посторив битмепы по соотв созданному повернутому шрифту (не пробовал — но не вижу причин почему не должно работать)
Проблемка решилась! Сёдня выдали снап и по ходу проект доведён до некотого эпапа когда можно отдохнуть.
S>1. Такой фокус точно пройдет c wglFontOutlines, но испольнозать их дорого.
Именно так и решил. В моём случае это приемлемые расходы и пойти на них — это дёшево.
проблема в использовании этой функции была в том, что получающаяся надпись был ОЧЕНЬ маленького размера (меньше точки). Всякие GetTextExpPoint32 отдохнули по полной программе (пришлось написать свою такую функцию).
В общем в результате я получил-таки полностью аппаратно ускоренный код, который и был отправлен на тестирование.
S>2. Текст пишется, (а не происходит вывод букв друг на друге) так как вывод Bitmap-а сдвигает текущую позиуию растра. По умолчанию — вправо на свой размер. Этим кажется можно управлять — и заставить его смещать его вниз. Тогда текст будет писаться вертикально.
...да, но буквы (в моём случае цифры) будут всё же с традиционной ориентацией.
S>3. Повернутые буквы можно получить посторив битмепы по соотв созданному повернутому шрифту (не пробовал — но не вижу причин почему не должно работать)
...пожалуй, что да, но это пока для меня сложновато, опять-таки просто не до того было.
Здравствуйте Sasparella, Вы писали:
S>а где wglMakeCurrent()? или вы его при создании делаете текущим и на всю жизнь? ИМНО лучше все таки делать его текущим только когда надо.
Сорри, что долго не отвечал — пока безлошадный.
Угу, делаю один раз в OnCreate. А что, так не принято? Если да то чем чревато?