在C ++ / OpenGL中没有边框的透明背景上显示图像

时间:2011-09-13 02:43:29

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

2 个答案:

答案 0 :(得分:1)

这是一个可以帮助你的工作基础样本(使用c ++和clr支持)。

您需要根据需要调整它(例如使用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;
}

答案 1 :(得分:0)

看起来你需要在Windows上使用它。你看过Layered Windows吗?

除非出于某种原因需要OpenGL用于图形,否则我认为最好将图像作为常规位图加载并直接将它们插入分层窗口。使用OpenGL,你需要绘制一个纹理贴图,然后取出该纹理并将其blit到分层窗口。