使用SDL2_ttf模糊文本时为什么会出现访问冲突错误?

时间:2016-04-07 16:35:59

标签: c++ sdl sdl-ttf

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

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);
}

1 个答案:

答案 0 :(得分:0)

在调试器中运行应用程序并中断异常。检查调用堆栈。如果您很幸运,它将陷入您自己的代码中发生异常的位置。如果异常不在陷阱中的代码模块中,请单击向上调用堆栈(在此处显示的列表中),直到到达代码中可以检查调用者参数的部分,它是通常很容易发现那时出错的地方。 0x44非常像ASCII&#39; $&#39;,你的txt中有$吗?