这是我的代码,但我无法移动。
我在每次执行此函数时添加了一些代码int rendSC()
,我在y轴添加了1个像素。
但它没有动。只显示它第一次画画。
这是我尝试过的一种方式:
rendsc()
。失败UpdateWindow()
InvalidWindow()
等来刷新窗口,现在就调用rendSC()
。也失败使用时间来致电rendSC()
。故障。
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[]=_T("TransparentGL");
const TCHAR wcWndName[]=_T("WS_EX_LAYERED OpenGL");
HDC hDC;
HGLRC m_hrc;
int w(240);
int h(240);
HDC pdcDIB;
HBITMAP hbmpDIB;
void *bmp_cnt(NULL);
int cxDIB(0);
int cyDIB(0);
BITMAPINFOHEADER BIH;
BOOL initSC()
{
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW );
glLoadIdentity();
}
BOOL renderSC()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
// DIB -> hDC
void draw(HDC pdcDest)
{
assert(pdcDIB);
verify(BitBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, SRCCOPY));
}
void CreateDIB(int cx, int cy)
{
assert(cx > 0);
assert(cy > 0);
cxDIB = cx ;
cyDIB = cy ;
int iSize = sizeof(BITMAPINFOHEADER);
memset(&BIH, 0, iSize);
BIH.biSize = iSize;
BIH.biWidth = cx;
BIH.biHeight = cy;
BIH.biPlanes = 1;
BIH.biBitCount = 24;
BIH.biCompression = BI_RGB;
if(pdcDIB)
verify(DeleteDC(pdcDIB));
pdcDIB = CreateCompatibleDC(NULL);
assert(pdcDIB);
if(hbmpDIB)
verify(DeleteObject(hbmpDIB));
hbmpDIB = CreateDIBSection(
pdcDIB,
(BITMAPINFO*)&BIH,
DIB_RGB_COLORS,
&bmp_cnt,
NULL,
0);
assert(hbmpDIB);
assert(bmp_cnt);
if(hbmpDIB)
SelectObject(pdcDIB, hbmpDIB);
}
BOOL CreateHGLRC()
{
DWORD dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;
PIXELFORMATDESCRIPTOR pfd ;
memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = dwFlags ;
pfd.iPixelType = PFD_TYPE_RGBA ;
pfd.cColorBits = 24 ;
pfd.cDepthBits = 32 ;
pfd.iLayerType = PFD_MAIN_PLANE ;
int PixelFormat = ChoosePixelFormat(pdcDIB, &pfd);
if (PixelFormat == 0){
assert(0);
return FALSE ;
}
BOOL bResult = SetPixelFormat(pdcDIB, PixelFormat, &pfd);
if (bResult==FALSE){
assert(0);
return FALSE ;
}
m_hrc = wglCreateContext(pdcDIB);
if (!m_hrc){
assert(0);
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch(msg)
{
case WM_ERASEBKGND:
return 0;
break;
case WM_CREATE:
break;
case WM_DESTROY:
if(m_hrc)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc) ;
}
PostQuitMessage(0) ;
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
renderSC(); // OpenGL -> DIB
draw(hDC); // DIB -> hDC
EndPaint(hWnd, &ps);
break;
case WM_SIZE:
w = LOWORD(lParam); h = HIWORD(lParam);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc);
CreateDIB(w, h);
CreateHGLRC();
verify(wglMakeCurrent(pdcDIB, m_hrc));
initSC();
resizeSC(w, h);
renderSC();
break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode)
{
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wc.lpszClassName = szAppName;
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if(!hWnd){
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
verify(SetLayeredWindowAttributes(hWnd, 0x0, 0, LWA_COLORKEY));
MSG msg;
while(1)
{
while (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else return 0;
}
}
return (FALSE);
}
答案 0 :(得分:0)
绘制位图上下文是个坏主意。在这种情况下,您将只获得软件上下文(这也意味着您将获得没有任何有用扩展的版本1.1上下文)。
但是,如果这符合您的需要,您将创建非双缓冲上下文,在这种情况下,您应该先调用glFinish
(而不是Flush),然后才能将DIB中的位复制到窗口。
首选使用带有PFD_DRAW_TO_WINDOW
的双缓冲窗口上下文,并避免绘制到位图上下文。
如果您仍希望将渲染结果导入DIB,您应该学习渲染到像FBO这样的纹理技术(将场景渲染到纹理中)以及通过从纹理中读取像素来抓取数据(还有几种方法可以做这一点)。
答案 1 :(得分:0)
现在,这可以成为这样一个窗口
但如果我点击窗口,它将冻结
#include "GLFW/glfw3.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <thread>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
#endif
GLFWwindow* f_window = NULL;
float ratio = 0;
int width, height;
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
static void mouse_callback(GLFWwindow* window, int a, int b, int c)
{
int xxx = 0;
}
#ifdef _WIN32
void Render();
void renderFunc();
void timerGlFunc();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static bool toDebug = false;
if (toDebug)
{
std::cout << __FUNCTION__ << " "; printf("%02x", msg); std::cout << " ";
toDebug = false;
}
//std::cout << __FUNCTION__ << " " << msg;
switch (msg)
{
case WM_LBUTTONDOWN:
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
std::cout << __FUNCTION__ << " "; printf("%02x", msg); std::cout << " ";
toDebug = true;
PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(xPos, yPos));
}
break;
case WM_NCLBUTTONDOWN:
std::cout << __FUNCTION__ << " "; printf("%02x", msg); std::cout << " ";
toDebug = true;
break;
case WM_SYSCOMMAND:
std::cout << __FUNCTION__ << " "; printf("%02x", msg); std::cout << " ";
toDebug = true;
break;
case WM_CAPTURECHANGED:
std::cout << __FUNCTION__ << " "; printf("%02x", msg); std::cout << " ";
toDebug = true;
break;
case WM_TIMER:
{
if (wParam == 1)
{
timerGlFunc();
}
//DefWindowProc(hWnd, msg, wParam, lParam);
}
break;
default:
//Render();
return DefWindowProc(hWnd, msg, wParam, lParam);;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
#endif
void mainDraw();
int main(void)
{
bool first = true;
std::thread t(mainDraw);
while (true)
{
if (first)
{
t.detach();
first = false;
}
Sleep(10);
}
exit(EXIT_SUCCESS);
return 0;
}
void mainDraw()
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_ALPHA_BITS, 8);
glfwWindowHint(GLFW_ALPHA_MASK, GL_TRUE);
glfwWindowHint(GLFW_DECORATED, GL_FALSE);
glfwWindowHint(GLFW_SAMPLES, 4);
char* title = "Transparent window example";
window = glfwCreateWindow(256, 256, title, NULL, NULL);
#ifdef _WIN32
HWND windowHandle = FindWindow(NULL, title);
if (windowHandle == NULL)
{
printf("NULL HWND");
}
SetWindowLong(windowHandle, GWL_WNDPROC, (LONG)WndProc);
SetTimer(windowHandle, 1, 20, NULL);
#endif
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
f_window = window;
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetWindowPos(window, 300, 300);
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_callback);
renderFunc();
//Sleep(10);
glfwDestroyWindow(window);
glfwTerminate();
}
void renderFunc()
{
BOOL ret;
MSG msg;
/*
while ((ret = GetMessage(&msg, nullptr, 0, 0)) != 0)
{
if (ret != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
*/
while (!glfwWindowShouldClose(f_window))
{
if ((ret = GetMessage(&msg, nullptr, 0, 0)) != 0)
{
if (ret != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
glfwGetFramebufferSize(f_window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
//Render();
Sleep(10);
glfwPollEvents();
}
}
void timerGlFunc()
{
if (!glfwWindowShouldClose(f_window))
{
glfwGetFramebufferSize(f_window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
Render();
glfwPollEvents();
}
}
void Render()
{
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.6f, -0.4f, 0.f);
glColor4f(0.f, 1.f, 0.f, 0.0f);
glVertex3f(0.6f, -0.4f, 0.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.f, 0.6f, 0.f);
glEnd();
glfwSwapBuffers(f_window);
}