c++ - 在 C++/OpenGL 中以无边框的透明背景显示图像

标签 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;
}

最佳答案

这是一个可以帮助您的工作基础示例(使用支持 clr 的 C++)。

您需要根据需要调整它(例如使用 DrawImage 而不是 FillEllipse)

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;

ref class MyForm : public Form
{
public:

    MyForm()
    {
        this->m_brush = gcnew SolidBrush(Color::Blue);

        this->m_canvas = gcnew System::Windows::Forms::Panel();
        this->m_canvas->BackColor = Color::Pink;
        this->m_canvas->Dock = System::Windows::Forms::DockStyle::Fill;
        this->m_canvas->Location = System::Drawing::Point(0, 0);
        this->m_canvas->Margin = System::Windows::Forms::Padding(0);
        this->m_canvas->Name = "Canvas";
        this->m_canvas->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::canvas_Paint);
        this->m_canvas->TabIndex = 0;

        this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
        this->BackColor = Color::Pink;
        this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
        this->ClientSize = System::Drawing::Size(200, 200);
        this->Controls->Add(this->m_canvas);
        this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &MyForm::form_KeyDown);
        this->TransparencyKey = Color::Pink;
        this->Name = "MyForm";
        this->Text = "MyForm";
    }

private:

    void canvas_Paint(Object^ sender, PaintEventArgs^ e) {
        e->Graphics->FillEllipse(this->m_brush, Rectangle(50, 50, 100, 100));
    }

    void form_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
        // Test key ...
        this->m_canvas->Invalidate();
        // ...
    }

    Brush^ m_brush;
    Panel^ m_canvas;
};

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    // Enabling Windows XP visual effects before any controls are created
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false); 

    // Create the main window and run it
    Application::Run(gcnew MyForm());
    return 0;
}

关于c++ - 在 C++/OpenGL 中以无边框的透明背景显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7396261/

相关文章:

c++ - 具有默认值的参数的自动类型推导

c++ - NSArray 如何取得 C++ 对象的所有权

java - 在 OpenGL 中获取相机在 X、Y 和 Z 轴上的弧度旋转?

c - OpenGL 三角形未显示

opengl - 在 Fragmentshader OpenGL 中访问不同的 Fragment

C++:如何在可变参数模板参数上调用带有类型参数的函数?

c++ - 使用数组防止 C++ 中的堆栈溢出?

c++ - 防止默认点击事件 (WinAPI)

opengl - 用顶点属性替换颜色

c++ - 将现有的 C++ openGL 项目从 glut/freeglut 转换为 glfw