- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试制作一个简单的游戏,当我尝试渲染我的 SDL_Texture
时,我遇到了一个莫名其妙的错误。我已正确设置所有内容,我能够使用 SDL_RenderClear
成功清除屏幕,并且我的纹理不为空,因此它应该已正确创建。但是当我尝试调用 render()
函数时出现错误,并且 SDL_GetError()
返回“Invalid texture”。
编辑:我现在已经按照要求创建了一个 MCVE,并且我对其进行了测试以验证它是否重现了错误。它应该在窗口中的路径“gfx/grid.bmp”中显示图像,但它却给了我错误。这是完整的 MCVE:
#include <SDL.h>
#include <string>
#include <iostream>
#undef main
class Texture{
private:
SDL_Texture* texture;
SDL_Renderer* renderer;
int width;
int height;
public:
Texture(){
texture = nullptr;
}
Texture (SDL_Renderer* ren, std::string path){
texture = nullptr;
SDL_Surface* surface = nullptr;
surface = SDL_LoadBMP(path.c_str());
if(surface == nullptr) return;
renderer = ren;
texture = SDL_CreateTextureFromSurface( renderer, surface );
if(texture == 0) return;
width = surface->w;
height = surface->h;
SDL_FreeSurface(surface);
std::cout << "Texture '" << path << "' successfully loaded\n";
}
bool loaded(){
return texture != 0;
}
bool render(int x = 0, int y = 0){
SDL_Rect dest;
dest.x = x;
dest.y = y;
dest.w = width;
dest.h = height;
return SDL_RenderCopy(renderer, texture, nullptr, &dest) == 0;
}
void unload(){
if(loaded()){
SDL_DestroyTexture(texture);
texture = nullptr;
renderer = nullptr;
width = 0;
height = 0;
}
}
~Texture(){
unload();
}
};
class CApp{
private:
bool running = true;
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
Texture graphic_grid;
bool render = true;
public:
int OnExecute();
bool OnInit();
void OnEvent(SDL_Event* event);
void OnRender();
void OnCleanup();
};
bool CApp::OnInit(){
if(SDL_Init(SDL_INIT_EVERYTHING) < 0){
return false;
}
if((window = SDL_CreateWindow("Simple Tic-Tac-Toe", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 600, 600, SDL_WINDOW_SHOWN)) == nullptr){
return false;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(renderer == nullptr){
std::cout << "Renderer failed to load! Error: " << SDL_GetError();
return false;
}
SDL_SetRenderDrawColor( renderer, 0xFF, 0xFF, 0xFF, 0xFF );
graphic_grid = Texture(renderer, "gfx/grid.bmp");
if(!graphic_grid.loaded()){
std::cout << "Image failed to load! Error: " << SDL_GetError();
return false;
}
std::cout << "Initialized fully\n";
return true;
}
void CApp::OnEvent(SDL_Event* event){
switch(event->type == SDL_QUIT){
running = false;
}
}
void CApp::OnRender(){
if(!render) return;
if(SDL_RenderClear(renderer) == 0){
std::cout << "Successfully cleared screen\n";
}
if(!graphic_grid.loaded()){
std::cout << "Texture not loaded!\n";
}else{
std::cout << "Texture not null!\n";
}
//This is the place where I get the "Invalid texture" error, everything else works fine
if(!graphic_grid.render()){
std::cout << "Failed to render image! Error: " << SDL_GetError() << '\n';
}
SDL_RenderPresent(renderer);
render = false;
}
void CApp::OnCleanup(){
graphic_grid.unload();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
renderer = nullptr;
window = nullptr;
SDL_Quit();
}
int CApp::OnExecute(){
if(OnInit() == false){
return -1;
}
SDL_Event event;
while(running){
while(SDL_PollEvent(&event)){
OnEvent(&event);
}
OnRender();
}
OnCleanup();
return 0;
}
int main(){
CApp theApp;
return theApp.OnExecute();
}
我四处搜索,找不到任何可以解释我的错误的内容。我能找到的最接近的东西是 this question ,但该错误是由渲染器在纹理之前被破坏引起的,这不是我的情况。
我真的希望有人能告诉我可能导致此错误的原因,我们将不胜感激!
最佳答案
你的问题是你正在这一行复制你的纹理
graphic_grid = Texture(renderer, "gfx/grid.bmp");
由于您没有定义复制赋值运算符或移动赋值,编译器会为您提供一个,它只是按原样复制成员。
一旦由 Texture(renderer, "gfx/grid.bmp");
创建的临时文件被销毁,graphic_grid.texture
就不再有效。您可以通过删除 Texture
析构函数来测试它,您应该会发现一切都按预期工作(当然您实际上不想这样做,它不是修复)。
如果您的 Texture
不打算被复制,您将需要实现移动赋值或复制赋值构造函数,最好是前者(并且由于您需要赋值,您还应该提供一个移动/复制构造函数,以及其他两个移动/复制方法,按照五的规则,或者至少显式删除
它们)。
请仔细阅读 0/3/5 的规则
Rule-of-Three becomes Rule-of-Five with C++11?
如果您使用的是 GCC,-Weffc++
标志会警告您一些像这样的狡猾类设计。
就我个人而言,我尽量将句柄和指针包装到 RAII 类型中,只要每个成员都对自己负责,您通常不必费心使用复制和移动构造函数。 std::unique_ptr
对此非常有效,例如:
template<typename T, void(*destroy)(T*), typename Ptr = std::unique_ptr<T, decltype(destroy)>>
struct Handle : public Ptr
{
Handle(T*&& p): Ptr{p, destroy}
{
if (!*this)
throw std::runtime_error{SDL_GetError()};
}
};
using Window_h = Handle<SDL_Window, SDL_DestroyWindow>;
using Surface_h = Handle<SDL_Surface, SDL_FreeSurface>;
// And so on for other handles
可以如下使用
Window_h window{SDL_CreateWindow(
"Hello world",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800, 600,
0
)};
如果你要像上面那样包装 SDL_Texture
那么你的 Texture
类将有一个隐式移动构造函数和移动赋值运算符,它们可以开箱即用(你会但是,必须摆脱 renderer
成员,或者以不同的方式处理它,例如将其设为 std::shared_ptr
这样它就不会与纹理一起被破坏,除非它引用计数为 0)。
您的代码还有其他一些奇怪的事情,例如过早地从构造函数返回。如果无法构造对象,则应抛出异常。
关于尝试呈现 SDL_Texture : Invalid texture 时出现 C++ SDL2 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25738096/
我的应用程序从一个有 5 个选项卡的选项卡栏 Controller 开始。一开始,第一个出现了它的名字,但其他四个没有名字,直到我点击它们。然后根据用户使用的语言显示名称。如何在选项卡栏出现之前设置选
我有嵌套数组 json 对象(第 1 层、第 2 层和第 3 层)。我的问题是数据表没有出现。任何相关的 CDN 均已导入。该表仅显示部分。我引用了很多网站,但都没有解决我的问题。 之前我使用标准表来
我正在尝试设置要显示的 Parse PFLoginViewController。这是我的一个 View Controller 的类。 import UIKit import Parse import
我遇到了这个问题,我绘制的对象没有出现在 GUI 中。我知道它正在被处理,因为数据被推送到日志文件。但是,图形没有出现。 这是我的一些代码: public static void main(Strin
我有一个树状图,其中包含出现这样的词...... TreeMap occurrence = new TreeMap (); 字符串 = 单词 整数 = 出现次数。 我如何获得最大出现次数 - 整数,
因此,我提示用户输入变量。如果变量小于 0 且大于 10。如果用户输入 10,我想要求用户再次输入数字。我问时间的时候输入4,它说你输入错误。但在第二次尝试时效果很好。例如:如果我输入 25,它会打印
我已经用 css overflow 属性做了一个例子。在这个例子中我遇到了一个溢出滚动的问题。滚动条出现了,但没有工作意味着每当将光标移动到滚动条时,在这个滚动条不活动的时间。我对此一无所知,所以请帮
我现在正在做一个元素。当您单击一个元素时,会出现以下信息,我想知道如何在您单击下一个元素而不重新单击同一元素时使其消失....例如,我的元素中有披萨,我想单击肉披萨看到浇头然后点击奶酪披萨看到浇头和肉
我有一个路由器模块,它将主题与正则表达式进行比较,并将出现的事件与一致的键掩码链接起来。 (它是一个简单的 url 路由过滤,如 symfony http://symfony.com/doc/curr
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: mysql_fetch_array() expects parameter 1 to be resource, bo
我在底部有一个带有工具栏的 View ,我正在使用 NavigationLink 导航到该 View 。但是当 View 出现时,工具栏显示得有点太低了。大约半秒钟后,它突然跳到位。它只会在应用程序启
我试图在我的应用程序上为背景音乐添加一个 AVAudioPlayer,我正在主屏幕上启动播放器,尝试在应用程序打开时开始播放但出现意外行为... 它播放并立即不断创建新玩家并播放这些玩家,因此同时播放
这是获取一个数字,获取其阶乘并将其加倍,但是由于基本情况,如果您输入 0,它会给出 2 作为答案,因此为了绕过它,我使用了 if 语句,但收到错误输入“if”时解析错误。如果你们能提供帮助,我真的很感
暂停期间抛出异常 android.os.DeadObjectException 在 android.os.BinderProxy.transactNative( native 方法) 在 androi
我已经为猜词游戏编写了一些代码。它从用户输入中读取字符并在单词中搜索该字符;根据字符是否在单词中,程序返回并控制一些变量。 代码如下: import java.util.Random; import
我是自动化领域的新手。这是我的简单 TestNG 登录代码,当我以 TestNG 身份运行该代码时,它会出现 java.lang.NullPointerException,双击它会突出显示我导航到 U
我是c#程序员,我习惯了c#的封装语法和其他东西。但是现在,由于某些原因,我应该用java写一些东西,我现在正在练习java一天!我要创建一个为我自己创建一个虚拟项目,以便让自己更熟悉 Java 的
我正在使用 Intellij,我的源类是 main.com.coding,我的资源文件是 main.com.testing。我将 spring.xml 文件放入资源文件中。 我的测试类位于 test.
我想要我的tests folder separate到我的应用程序代码。我的项目结构是这样的 myproject/ myproject/ myproject.py moduleon
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 6 年前。 因此,我尝试比较 2 个值,一个
我是一名优秀的程序员,十分优秀!