繁体   English   中英

为什么在使用SDL2_ttf书写文本时出现访问冲突错误?

[英]Why Am I Getting an Access Violation Error When Blitting Text With SDL2_ttf?

我试图将SDL_ttf集成到我最近编写的粒子生成器程序中,但是却不断遇到运行时错误: Access violation reading location 0x00000044. 当我尝试在游戏屏幕上涂抹文本表面时,会发生这种情况。 我已经遍历我的代码几次,过去也遇到过类似的问题,但是我无法弄清楚这个问题。 最可能的问题是什么?

该错误发生在Text.h中:

#pragma once

#include "System.h"
#include <iostream>
#include <sstream>

class Text {
public:
    Text(const char *fontaddress = "times.ttf", int size = 30, const char
       *begintext = "0", int x = 0, int y = 0, SDL_Color color = { 255, 255, 255 }) {
        font = TTF_OpenFont(fontaddress, size);

        drawpos.x = x;
        drawpos.y = y;

        textcolor = color;

        text = TTF_RenderText_Solid(font, begintext, textcolor);
        if (!text)
            std::cout << "damn" << std::endl;
    }
    ~Text() {
        if (text)
            SDL_FreeSurface(text);
        TTF_CloseFont(font);
    }

    void SetText(const char *txt);
    void SetText(int txt);
    void DrawText();
private:
    TTF_Font *font;
    SDL_Rect drawpos;
    SDL_Color textcolor;
    SDL_Surface *text;
};

inline void Text::SetText(const char *txt) {
    if (text)
        SDL_FreeSurface(text);

    text = TTF_RenderText_Solid(font, txt, textcolor);
}


inline void Text::SetText(int txt) {
    if (text)
        SDL_FreeSurface(text);

    std::stringstream s;
    s << txt;
    text = TTF_RenderText_Solid(font, s.str().c_str(), textcolor);
}

inline void Text::DrawText() {
    static SDL_Surface *const screen = System::GetInstance().GetScreen();
    SDL_BlitSurface(text, NULL, screen, &drawpos);
     // ^ This line throws the exception
}

Bar.h:

#pragma once

#include <SDL.h>
#include <iostream>
#include "System.h"
#include "Text.h"

class Bar {
public:
    Bar(const int xpos = 0, const int ypos = 0, unsigned width = 0, unsigned    height = 0, const Uint32 c = SDL_MapRGB(System::GetInstance().GetScreen()-   >format, 0, 0, 0), const char *address = "times.ttf",
        int sz = 30, const char *bgtext = "0", SDL_Color co = { 255, 255,   255 }) : max_w(width), color(c), colortext(address, sz, bgtext, xpos - 50, ypos, co) {
        bar.x = xpos;
        bar.y = ypos;
        bar.w = width;
        bar.h = height;

        modval = max_w / 255;
        if (!modval)
            modval = 1;
        if (max_w < 255) {
            std::cerr << "invalid width; below 255" << std::endl;
        }
        colorval = width / modval;
    }

    void Modify(int width_modifier);
    void Draw();
    Uint8 GetColorVal();
private:
    SDL_Rect bar;
    unsigned max_w;
    Uint32 color;
    Uint8 modval;   // number of pixels (in width) required to advance or decrement the color value by 1
    Uint8 colorval; // the color value modified when width is changed. Determined by 
           // modval. This value will be used by RGBTable class for text (on-screen value display) and particle color creation
    Text colortext;
};

//inlined methods

//modifies the width of a bar
inline void Bar::Modify(int width_modifier) {
    if (bar.w + width_modifier < 0 || bar.w + width_modifier > max_w)
        return;

        bar.w += width_modifier;
        if (bar.w % modval == 0) {
            colorval = bar.w / modval;
            colortext.SetText(colorval);
        }
}


//draws bar to system screen
inline void Bar::Draw() {
    static SDL_Surface *screen = System::GetInstance().GetScreen();
    SDL_FillRect(screen, &bar, color);
    colortext.DrawText();
}


//returns the 8bit color value represented by the width of a bar
inline Uint8 Bar::GetColorVal() {
    return colorval;
}

ColorTable.h:

#pragma once 

#include "System.h"
#include "Bar.h"
#include <array>

class ColorTable {
public:
    static bool needupdate;
    static ColorTable &GetInstance();

    void Input();
    void Draw();
    Uint32 MakeColor();
private:
    ColorTable(int top_left_x, int top_left_y, unsigned width, int height,  int sepval) { 
        static SDL_Surface *screen = System::GetInstance().GetScreen();

        bars[0] = Bar(top_left_x, top_left_y, width, height, SDL_MapRGB(screen->format, 255, 0, 0));
        bars[1] = Bar(top_left_x, top_left_y + height + sepval, width, height, SDL_MapRGB(screen->format, 0, 255, 0));
        bars[2] = Bar(top_left_x, top_left_y + (sepval *2) + (height * 2), width, height, SDL_MapRGB(screen->format, 0, 0, 255));

        activebar = bars.begin();
    }

    std::array<Bar, 3> bars;
    std::array<Bar, 3>::iterator activebar;
    const Uint8 *key = SDL_GetKeyboardState(NULL);
};

inline ColorTable &ColorTable::GetInstance() {
    static ColorTable table(750, 620, 510, 50, 10);
    return table;
}

inline void ColorTable::Draw() {
    bars[0].Draw();
    bars[1].Draw();
    bars[2].Draw();
}

inline Uint32 ColorTable::MakeColor() {
    static SDL_Surface *screen = System::GetInstance().GetScreen();

    Uint8 r = bars[0].GetColorVal();
    Uint8 g = bars[1].GetColorVal();
    Uint8 b = bars[2].GetColorVal();

    return SDL_MapRGB(screen->format, r, g, b);
}

在调试器中运行该应用程序,并在异常处中断。 检查调用堆栈。 如果幸运的话,它将困在您自己的代码中发生异常的地方。 如果异常不在陷阱的代码模块中,请单击调用堆栈上的方法(在此处显示的列表下方),直到到达可以检查调用者参数的代码部分为止,通常很容易发现当时哪里出错了。 0x44可疑地类似于ASCII'$',您的txt中有$吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM