在 C++ 中显示无边框透明背景的图像/ OpenGL
我正在寻找一种方法来在透明背景无边框的窗口上显示两个 png 图像(事实上,它将是数字,我的目标是创建一个用于实时流媒体的叠加层以显示玩家得分和一些其他附加内容)。这样我们就可以看到后面窗口上的分数。
有什么办法可以做类似的事情吗?我已经用 SDL、纹理尝试了很多东西,但没有任何结果能让我满意。我发现的最好的结果是一些脏代码几乎可以工作但完全无法使用。
如果可能,该解决方案可以添加这样的功能:当您在 2 个分数之一上向左或向右单击时,它会增加或减少。
编辑:这是我当前的代码。我开始新的工作,没有任何以前的脏代码,因为我想了解我在做什么。我将 2 个数字显示为纹理,现在我想删除窗口的边框和标题栏,并使背景透明。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "sdlglutils.h"
#include <assert.h>
#include <tchar.h>
using namespace std;
int overlay;
int TimerEnabled;
GLfloat posX, posY, posZ;
GLuint texture_0, texture_1, texture_2, texture_3;
void Initialize()
{
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
glEnable(GL_TEXTURE_2D);
}
void Reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w/(GLfloat)h,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
texture_0 = loadTexture("0.png");
texture_1 = loadTexture("1.png");
texture_2 = loadTexture("2.png");
texture_3 = loadTexture("3.png");
return;
}
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glTranslatef(posX,posY,posZ);
glScalef(1.0f,1.0f,1.0f);
glPushMatrix();
glTranslated(-6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_1);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_2);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glFlush();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Draw();
glutSwapBuffers();
}
void KeyboardSpecialEvent( int key, int x, int y)
{
switch(key)
{
case(GLUT_KEY_UP) :
{
posY += 0.3;
}break;
case(GLUT_KEY_DOWN) :
{
posY -= 0.3;
}break;
case(GLUT_KEY_LEFT) :
{
posX -= 0.3;
}break;
case(GLUT_KEY_RIGHT) :
{
posX += 0.3;
}break;
}
}
void MouseEvent( int button, int state, int x, int y){ };
void MotionMouseEvent( int x, int y ){ };
void IdleEvent(){ };
void TimerEvent(int time)
{
glutPostRedisplay();
if(TimerEnabled)
glutTimerFunc(10, TimerEvent, time);
}
void KeyboardEvent( unsigned char key, int x, int y)
{
switch(key)
{
case ' ' :
{
TimerEnabled = !TimerEnabled;
if (TimerEnabled)
glutTimerFunc(40, TimerEvent, 0);
}
break;
case 'q' :
{
exit(0);
}
break;
}
}
int main(int argc, char** argv)
{
posX = 0;
posY = 0;
posZ = -25;
TimerEnabled = 1;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(1600,900);
glutInitWindowPosition(0,0);
overlay = glutCreateWindow("ScoreOverlay");
//glutFullScreen();
Initialize();
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(KeyboardEvent);
glutSpecialFunc(KeyboardSpecialEvent);
glutMouseFunc(MouseEvent);
glutMotionFunc(MotionMouseEvent);
glutIdleFunc(IdleEvent);
glutTimerFunc(40, TimerEvent, 0);
glutMainLoop();
return 0;
}
I am looking for a way to display two png images (in fact, it will be numbers, my aim is to create an overlay for live streaming to display players score and some further additional content) on a window with transparent background with no border. So that we just see the score over the window placed behind.
Is there any way to do something like that ? I have already tried many things with SDL, textures, but nothing led me to any satisfying result. The best I found was some dirty code almost working but completely unusable.
If possible, the solution may let possible to add the functionality that when you click left or right on one of the 2 scores, it is incremented or decremented.
Edit: Here is my current code. I started new without any bit of the dirty code I had before, because I would like to understand what I am doing. I have my 2 numbers displayed as textures, now I would like to remove borders and title bar of my window, and make my background transparent.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "sdlglutils.h"
#include <assert.h>
#include <tchar.h>
using namespace std;
int overlay;
int TimerEnabled;
GLfloat posX, posY, posZ;
GLuint texture_0, texture_1, texture_2, texture_3;
void Initialize()
{
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
glEnable(GL_TEXTURE_2D);
}
void Reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w/(GLfloat)h,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
texture_0 = loadTexture("0.png");
texture_1 = loadTexture("1.png");
texture_2 = loadTexture("2.png");
texture_3 = loadTexture("3.png");
return;
}
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glTranslatef(posX,posY,posZ);
glScalef(1.0f,1.0f,1.0f);
glPushMatrix();
glTranslated(-6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_1);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_2);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glFlush();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Draw();
glutSwapBuffers();
}
void KeyboardSpecialEvent( int key, int x, int y)
{
switch(key)
{
case(GLUT_KEY_UP) :
{
posY += 0.3;
}break;
case(GLUT_KEY_DOWN) :
{
posY -= 0.3;
}break;
case(GLUT_KEY_LEFT) :
{
posX -= 0.3;
}break;
case(GLUT_KEY_RIGHT) :
{
posX += 0.3;
}break;
}
}
void MouseEvent( int button, int state, int x, int y){ };
void MotionMouseEvent( int x, int y ){ };
void IdleEvent(){ };
void TimerEvent(int time)
{
glutPostRedisplay();
if(TimerEnabled)
glutTimerFunc(10, TimerEvent, time);
}
void KeyboardEvent( unsigned char key, int x, int y)
{
switch(key)
{
case ' ' :
{
TimerEnabled = !TimerEnabled;
if (TimerEnabled)
glutTimerFunc(40, TimerEvent, 0);
}
break;
case 'q' :
{
exit(0);
}
break;
}
}
int main(int argc, char** argv)
{
posX = 0;
posY = 0;
posZ = -25;
TimerEnabled = 1;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(1600,900);
glutInitWindowPosition(0,0);
overlay = glutCreateWindow("ScoreOverlay");
//glutFullScreen();
Initialize();
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(KeyboardEvent);
glutSpecialFunc(KeyboardSpecialEvent);
glutMouseFunc(MouseEvent);
glutMotionFunc(MotionMouseEvent);
glutIdleFunc(IdleEvent);
glutTimerFunc(40, TimerEvent, 0);
glutMainLoop();
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个可以帮助您的工作基础示例(使用带有 clr 支持的 c++)。
您需要根据您的需要进行调整(例如使用 DrawImage 而不是 FillEllipse)
Here is a working base sample (using c++ with clr support) that could help you.
You need to adapt it to your need (for example use DrawImage instead of FillEllipse)
看起来您在 Windows 上需要这个。您看过分层Windows吗?
除非您出于某种原因需要 OpenGL 来处理图形,否则我认为您最好将图像作为常规位图加载并直接将它们传输到分层窗口。使用 OpenGL,您需要绘制纹理贴图,然后获取该纹理并将其传输到分层窗口。
It looks like you need this on Windows. Have you looked at Layered Windows?
Unless you need OpenGL for the graphics for some reason I think you'll be better off loading your images as regular bitmaps and blitting them to the layered window directly. Using OpenGL you would need to draw to a texture map, then take that texture and blit it to the layered window.