fix some and add spaceship with shaders and textures

This commit is contained in:
Vlad 2025-12-06 21:49:09 +06:00
parent 1c9b1b1969
commit 70db96a52e
11 changed files with 1020 additions and 786 deletions

View File

@ -2,26 +2,25 @@
#include "AnimatedModel.h" #include "AnimatedModel.h"
#include "BoneAnimatedModel.h" #include "BoneAnimatedModel.h"
#include "Utils.h" #include "Utils.h"
//#include "OpenGlExtensions.h"
#include <iostream> #include <iostream>
#include "TextureManager.h" #include "TextureManager.h"
#include "TextModel.h" #include "TextModel.h"
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
namespace ZL #ifdef __ANDROID__
{ #include <android/log.h>
const char* CONST_ZIP_FILE = ""; #endif
Game::Game() namespace ZL {
: window(nullptr) const char *CONST_ZIP_FILE = "";
, glContext(nullptr)
, newTickCount(0)
, lastTickCount(0)
{
}
Game::~Game() { Game::Game()
: window(nullptr), glContext(nullptr), newTickCount(0), lastTickCount(0),
resourcesLoaded(false), modelLoaded(false) {
}
Game::~Game() {
if (glContext) { if (glContext) {
SDL_GL_DeleteContext(glContext); SDL_GL_DeleteContext(glContext);
} }
@ -29,37 +28,115 @@ Game::~Game() {
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
} }
SDL_Quit(); SDL_Quit();
} }
void Game::setup() { void Game::setup() {
glContext = SDL_GL_CreateContext(ZL::Environment::window); glContext = SDL_GL_CreateContext(ZL::Environment::window);
// ZL::BindOpenGlFunctions();
// ZL::CheckGlError();
// Initialize renderer // Initialize renderer
renderer.InitOpenGL();
/*#ifdef EMSCRIPTEN #ifdef __ANDROID__
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE); __android_log_print(ANDROID_LOG_INFO, "Game", "Start for Android");
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
const char* testFiles[] = {
"resources/spaceship004.txt",
"shaders/default.vertex",
"shaders/default_android.fragment",
"shaders/defaultColor.vertex",
"shaders/defaultColor_android.fragment",
"resources/sship001x.bmp",
nullptr
};
for (int i = 0; testFiles[i] != nullptr; i++) {
SDL_RWops* file = SDL_RWFromFile(testFiles[i], "rb");
if (file) {
Sint64 size = SDL_RWsize(file);
__android_log_print(ANDROID_LOG_INFO, "Game", "Found: %s (size: %lld)", testFiles[i], size);
SDL_RWclose(file);
} else {
__android_log_print(ANDROID_LOG_WARN, "Game", "Not found: %s (SDL error: %s)",
testFiles[i], SDL_GetError());
}
}
try {
__android_log_print(ANDROID_LOG_INFO, "Game", "Shaders...");
renderer.shaderManager.AddShaderFromFiles("default",
"shaders/default.vertex",
"shaders/default_android.fragment",
CONST_ZIP_FILE);
renderer.shaderManager.AddShaderFromFiles("defaultColor",
"shaders/defaultColor.vertex",
"shaders/defaultColor_android.fragment",
CONST_ZIP_FILE);
__android_log_print(ANDROID_LOG_INFO, "Game", "Textures...");
try {
spaceshipTexture = std::make_shared<Texture>(
CreateTextureDataFromBmp32("resources/sship001x.bmp")
);
} catch (const std::exception& e) {
spaceshipTexture = nullptr;
}
__android_log_print(ANDROID_LOG_INFO, "Game", "Model...");
std::string modelPaths[] = {
"resources/spaceship004.txt",
""
};
bool modelLoadSuccess = false;
for (int i = 0; !modelLoadSuccess && !modelPaths[i].empty(); i++) {
try {
spaceshipBase = LoadFromTextFile02(modelPaths[i]);
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
spaceship.AssignFrom(spaceshipBase);
spaceship.RefreshVBO();
modelLoaded = true;
modelLoadSuccess = true;
__android_log_print(ANDROID_LOG_INFO, "Game", "Model loaded successfully from: %s", modelPaths[i].c_str());
} catch (const std::exception& e) {
__android_log_print(ANDROID_LOG_WARN, "Game", "Failed to load model from %s: %s",
modelPaths[i].c_str(), e.what());
}
}
resourcesLoaded = (spaceshipTexture != nullptr && modelLoaded);
} catch (const std::exception& e) {
__android_log_print(ANDROID_LOG_ERROR, "Game", "Setup failed: %s", e.what());
resourcesLoaded = false;
}
#else #else
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE); // Десктопная версия
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE); renderer.shaderManager.AddShaderFromFiles("default",
#endif "./shaders/default.vertex",
"./shaders/default_desktop.fragment",
CONST_ZIP_FILE);
renderer.shaderManager.AddShaderFromFiles("defaultColor",
"./shaders/defaultColor.vertex",
"./shaders/defaultColor_desktop.fragment",
CONST_ZIP_FILE);
//Load texture //Load texture
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sship001x.png")); spaceshipTexture = std::make_shared<Texture>(
CreateTextureDataFromPng("./resources/sship001x.png"));
spaceshipBase = LoadFromTextFile02("./resources/spaceship004.txt"); spaceshipBase = LoadFromTextFile02("./resources/spaceship004.txt");
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0))); spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
spaceship.AssignFrom(spaceshipBase); spaceship.AssignFrom(spaceshipBase);
spaceship.RefreshVBO(); spaceship.RefreshVBO();
*/ resourcesLoaded = true;
modelLoaded = true;
#endif
}
renderer.InitOpenGL(); void Game::drawScene() {
}
void Game::drawScene() {
static const std::string defaultShaderName = "default"; static const std::string defaultShaderName = "default";
static const std::string vPositionName = "vPosition"; static const std::string vPositionName = "vPosition";
static const std::string vTexCoordName = "vTexCoord"; static const std::string vTexCoordName = "vTexCoord";
@ -70,7 +147,11 @@ void Game::drawScene() {
glViewport(0, 0, Environment::width, Environment::height); glViewport(0, 0, Environment::width, Environment::height);
/*CheckGlError(); if (!resourcesLoaded) {
glClearColor(0.2f, 0.3f, 0.8f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return;
}
renderer.shaderManager.PushShader(defaultShaderName); renderer.shaderManager.PushShader(defaultShaderName);
renderer.RenderUniform1i(textureUniformName, 0); renderer.RenderUniform1i(textureUniformName, 0);
@ -78,29 +159,32 @@ void Game::drawScene() {
renderer.EnableVertexAttribArray(vTexCoordName); renderer.EnableVertexAttribArray(vTexCoordName);
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
static_cast<float>(Environment::width) / static_cast<float>(Environment::height), static_cast<float>(Environment::width) /
static_cast<float>(Environment::height),
1, 1000); 1, 1000);
renderer.PushMatrix(); renderer.PushMatrix();
renderer.LoadIdentity(); renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f*Environment::zoom }); renderer.TranslateMatrix({0, 0, -1.0f * Environment::zoom});
renderer.RotateMatrix(QuatFromRotateAroundX(M_PI/6.0)); renderer.RotateMatrix(QuatFromRotateAroundX(M_PI / 6.0));
//renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha)); //renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha));
if (spaceshipTexture) {
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID()); glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
renderer.DrawVertexRenderStruct(spaceship); renderer.DrawVertexRenderStruct(spaceship);
} else {
renderer.DrawVertexRenderStruct(spaceship);
}
renderer.PopMatrix(); renderer.PopMatrix();
renderer.PopProjectionMatrix(); renderer.PopProjectionMatrix();
renderer.DisableVertexAttribArray(vPositionName); renderer.DisableVertexAttribArray(vPositionName);
renderer.DisableVertexAttribArray(vTexCoordName); renderer.DisableVertexAttribArray(vTexCoordName);
renderer.shaderManager.PopShader();*/ renderer.shaderManager.PopShader();
}
//CheckGlError(); void Game::processTickCount() {
}
void Game::processTickCount() {
if (lastTickCount == 0) { if (lastTickCount == 0) {
lastTickCount = SDL_GetTicks64(); lastTickCount = SDL_GetTicks64();
@ -118,11 +202,10 @@ void Game::processTickCount() {
lastTickCount = newTickCount; lastTickCount = newTickCount;
} }
} }
void Game::render() { void Game::render() {
SDL_GL_MakeCurrent(ZL::Environment::window, glContext); SDL_GL_MakeCurrent(ZL::Environment::window, glContext);
//ZL::CheckGlError();
glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -131,21 +214,19 @@ void Game::render() {
processTickCount(); processTickCount();
SDL_GL_SwapWindow(ZL::Environment::window); SDL_GL_SwapWindow(ZL::Environment::window);
} }
void Game::update() { void Game::update() {
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) { if (event.type == SDL_QUIT) {
Environment::exitGameLoop = true; Environment::exitGameLoop = true;
} } else if (event.type == SDL_MOUSEWHEEL) {
else if (event.type == SDL_MOUSEWHEEL) {
static const float zoomstep = 2.0f; static const float zoomstep = 2.0f;
if (event.wheel.y > 0) { if (event.wheel.y > 0) {
Environment::zoom -= zoomstep; Environment::zoom -= zoomstep;
} } else if (event.wheel.y < 0) {
else if (event.wheel.y < 0) {
Environment::zoom += zoomstep; Environment::zoom += zoomstep;
} }
if (Environment::zoom < zoomstep) { if (Environment::zoom < zoomstep) {
@ -162,6 +243,6 @@ void Game::update() {
} }
render(); render();
} }
} // namespace ZL } // namespace ZL

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
//#include "OpenGlExtensions.h"
#include "Renderer.h" #include "Renderer.h"
#include "Environment.h" #include "Environment.h"
#include "TextureManager.h" #include "TextureManager.h"
@ -9,34 +8,41 @@
namespace ZL { namespace ZL {
class Game { class Game {
public: public:
Game(); Game();
~Game(); ~Game();
void setup(); void setup();
void update(); void update();
void render(); void render();
bool shouldExit() const { return Environment::exitGameLoop; } bool shouldExit() const { return Environment::exitGameLoop; }
private: private:
void processTickCount(); void processTickCount();
void drawScene(); void drawScene();
SDL_Window* window; SDL_Window *window;
SDL_GLContext glContext; SDL_GLContext glContext;
Renderer renderer; Renderer renderer;
size_t newTickCount; size_t newTickCount;
size_t lastTickCount; size_t lastTickCount;
bool resourcesLoaded;
bool modelLoaded;
static const size_t CONST_TIMER_INTERVAL = 10; static const size_t CONST_TIMER_INTERVAL = 10;
static const size_t CONST_MAX_TIME_INTERVAL = 1000; static const size_t CONST_MAX_TIME_INTERVAL = 1000;
std::shared_ptr<Texture> spaceshipTexture; std::shared_ptr <Texture> spaceshipTexture;
VertexDataStruct spaceshipBase; VertexDataStruct spaceshipBase;
VertexRenderStruct spaceship; VertexRenderStruct spaceship;
}; };
} // namespace ZL } // namespace ZL

View File

@ -1,11 +1,14 @@
#include "ShaderManager.h" #include "ShaderManager.h"
#include <iostream> #include <iostream>
#include <SDL.h>
#ifdef __ANDROID__
#include <android/log.h>
#endif
namespace ZL { namespace ZL {
ShaderResource::ShaderResource(const std::string& vertexCode, const std::string& fragmentCode) ShaderResource::ShaderResource(const std::string &vertexCode, const std::string &fragmentCode) {
{
const int CONST_INFOLOG_LENGTH = 256; const int CONST_INFOLOG_LENGTH = 256;
@ -22,8 +25,8 @@ namespace ZL {
int vertexCodeLength = static_cast<int>(strlen(vertexCode.c_str())); int vertexCodeLength = static_cast<int>(strlen(vertexCode.c_str()));
int fragmentCodeLength = static_cast<int>(strlen(fragmentCode.c_str())); int fragmentCodeLength = static_cast<int>(strlen(fragmentCode.c_str()));
const char* vc = &vertexCode[0]; const char *vc = &vertexCode[0];
const char* fc = &fragmentCode[0]; const char *fc = &fragmentCode[0];
vertexShader = glCreateShader(GL_VERTEX_SHADER); vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength); glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength);
@ -39,13 +42,19 @@ namespace ZL {
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled);
glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
if (!vertexShaderCompiled) if (!vertexShaderCompiled) {
{ #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to compile vertex shader: %s", infoLog);
#endif
throw std::runtime_error("Failed to compile vertex shader code!"); throw std::runtime_error("Failed to compile vertex shader code!");
} }
if (!fragmentShaderCompiled) if (!fragmentShaderCompiled) {
{ #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to compile fragment shader: %s", infoLog);
#endif
throw std::runtime_error("Failed to compile fragment shader code!"); throw std::runtime_error("Failed to compile fragment shader code!");
} }
@ -62,20 +71,21 @@ namespace ZL {
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked);
glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
if (!programLinked) if (!programLinked) {
{
shaderProgram = 0; shaderProgram = 0;
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
"Failed to link shader program: %s", infoLog);
#endif
throw std::runtime_error("Failed to link shader program!"); throw std::runtime_error("Failed to link shader program!");
} }
//================= Parsing all uniforms ================
int dummySize; //Dummy int dummySize; //Dummy
int dummyLen; //Dummy int dummyLen; //Dummy
GLenum dummyEnum; GLenum dummyEnum;
//================= Parsing all uniforms ================
int activeUniforms; int activeUniforms;
const int CONST_UNIFORM_NAME_LENGTH = 256; const int CONST_UNIFORM_NAME_LENGTH = 256;
@ -83,9 +93,9 @@ namespace ZL {
glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &activeUniforms); glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &activeUniforms);
for (int i = 0; i < activeUniforms; i++) for (int i = 0; i < activeUniforms; i++) {
{ glGetActiveUniform(shaderProgram, i, CONST_UNIFORM_NAME_LENGTH, &dummyLen, &dummySize,
glGetActiveUniform(shaderProgram, i, CONST_UNIFORM_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, uniformName); &dummyEnum, uniformName);
uniformList[uniformName] = glGetUniformLocation(shaderProgram, uniformName); uniformList[uniformName] = glGetUniformLocation(shaderProgram, uniformName);
} }
@ -98,36 +108,48 @@ namespace ZL {
glGetProgramiv(shaderProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs); glGetProgramiv(shaderProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs);
for (int i = 0; i < activeAttribs; i++) for (int i = 0; i < activeAttribs; i++) {
{ glGetActiveAttrib(shaderProgram, i, CONST_ATTRIB_NAME_LENGTH, &dummyLen, &dummySize,
glGetActiveAttrib(shaderProgram, i, CONST_ATTRIB_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, attribName); &dummyEnum, attribName);
attribList[attribName] = glGetAttribLocation(shaderProgram, attribName); attribList[attribName] = glGetAttribLocation(shaderProgram, attribName);
} }
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Shader created successfully, program ID: %u", shaderProgram);
#endif
} }
ShaderResource::~ShaderResource() ShaderResource::~ShaderResource() {
{ if (shaderProgram != 0) {
if (shaderProgram != 0)
{
glDeleteProgram(shaderProgram); glDeleteProgram(shaderProgram);
shaderProgram = 0; shaderProgram = 0;
} }
} }
GLuint ShaderResource::getShaderProgram() GLuint ShaderResource::getShaderProgram() {
{
return shaderProgram; return shaderProgram;
} }
void ShaderManager::AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName) void ShaderManager::AddShaderFromFiles(const std::string &shaderName,
{ const std::string &vertexShaderFileName,
const std::string &fragmentShaderFileName,
const std::string &ZIPFileName) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Loading shader: %s", shaderName.c_str());
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Vertex shader: %s", vertexShaderFileName.c_str());
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
"Fragment shader: %s", fragmentShaderFileName.c_str());
#endif
std::string vertexShader; std::string vertexShader;
std::string fragmentShader; std::string fragmentShader;
if (!ZIPFileName.empty()){ if (!ZIPFileName.empty()) {
std::vector<char> vertexShaderData; std::vector<char> vertexShaderData;
std::vector<char> fragmentShaderData; std::vector<char> fragmentShaderData;
@ -138,23 +160,22 @@ namespace ZL {
vertexShader = std::string(vertexShaderData.begin(), vertexShaderData.end()); vertexShader = std::string(vertexShaderData.begin(), vertexShaderData.end());
fragmentShader = std::string(fragmentShaderData.begin(), fragmentShaderData.end()); fragmentShader = std::string(fragmentShaderData.begin(), fragmentShaderData.end());
}else{ } else {
vertexShader = readTextFile(vertexShaderFileName); vertexShader = readTextFile(vertexShaderFileName);
fragmentShader = readTextFile(fragmentShaderFileName); fragmentShader = readTextFile(fragmentShaderFileName);
} }
///std::cout << "Shader: "<< vertexShader << std::endl; ///std::cout << "Shader: "<< vertexShader << std::endl;
shaderResourceMap[shaderName] = std::make_shared<ShaderResource>(vertexShader, fragmentShader); shaderResourceMap[shaderName] = std::make_shared<ShaderResource>(vertexShader,
fragmentShader);
} }
void ShaderManager::PushShader(const std::string& shaderName) void ShaderManager::PushShader(const std::string &shaderName) {
{ if (shaderStack.size() >= CONST_MAX_SHADER_STACK_SIZE) {
if (shaderStack.size() >= CONST_MAX_SHADER_STACK_SIZE)
{
throw std::runtime_error("Shader stack overflow!"); throw std::runtime_error("Shader stack overflow!");
} }
if (shaderResourceMap.find(shaderName) == shaderResourceMap.end()) if (shaderResourceMap.find(shaderName) == shaderResourceMap.end()) {
{
throw std::runtime_error("Shader does not exist!"); throw std::runtime_error("Shader does not exist!");
} }
@ -164,29 +185,22 @@ namespace ZL {
} }
void ShaderManager::PopShader() void ShaderManager::PopShader() {
{ if (shaderStack.size() == 0) {
if (shaderStack.size() == 0)
{
throw std::runtime_error("Shader stack underflow!"); throw std::runtime_error("Shader stack underflow!");
} }
shaderStack.pop(); shaderStack.pop();
if (shaderStack.size() == 0) if (shaderStack.size() == 0) {
{
glUseProgram(0); glUseProgram(0);
} } else {
else
{
glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram()); glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram());
} }
} }
std::shared_ptr<ShaderResource> ShaderManager::GetCurrentShader() std::shared_ptr <ShaderResource> ShaderManager::GetCurrentShader() {
{ if (shaderStack.size() == 0) {
if (shaderStack.size() == 0)
{
throw std::runtime_error("Shader stack underflow!"); throw std::runtime_error("Shader stack underflow!");
} }
@ -196,16 +210,12 @@ namespace ZL {
} }
ShaderSetter::ShaderSetter(ShaderManager &inShaderManager, const std::string &shaderName)
: shaderManager(inShaderManager) {
ShaderSetter::ShaderSetter(ShaderManager& inShaderManager, const std::string& shaderName)
: shaderManager(shaderManager)
{
shaderManager.PushShader(shaderName); shaderManager.PushShader(shaderName);
} }
ShaderSetter::~ShaderSetter() ShaderSetter::~ShaderSetter() {
{
shaderManager.PopShader(); shaderManager.PopShader();
} }

View File

@ -5,29 +5,28 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
namespace ZL #ifdef __ANDROID__
{ #include <android/log.h>
#endif
namespace ZL {
VertexDataStruct LoadFromTextFile(const std::string& fileName, const std::string& ZIPFileName) VertexDataStruct LoadFromTextFile(const std::string &fileName, const std::string &ZIPFileName) {
{
VertexDataStruct result; VertexDataStruct result;
std::ifstream filestream; std::ifstream filestream;
std::istringstream zipStream; std::istringstream zipStream;
if (!ZIPFileName.empty()) if (!ZIPFileName.empty()) {
{
std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName); std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName);
std::string fileContents(fileData.begin(), fileData.end()); std::string fileContents(fileData.begin(), fileData.end());
zipStream.str(fileContents); zipStream.str(fileContents);
} } else {
else
{
filestream.open(fileName); filestream.open(fileName);
} }
// Создаем ссылку f на нужный поток после этого код ниже остается без изменений // Создаем ссылку f на нужный поток после этого код ниже остается без изменений
std::istream& f = (!ZIPFileName.empty()) ? static_cast<std::istream&>(zipStream) : static_cast<std::istream&>(filestream); std::istream &f = (!ZIPFileName.empty()) ? static_cast<std::istream &>(zipStream)
: static_cast<std::istream &>(filestream);
//Skip first 5 lines //Skip first 5 lines
@ -47,16 +46,14 @@ namespace ZL
if (std::regex_search(tempLine, match, pattern_count)) { if (std::regex_search(tempLine, match, pattern_count)) {
std::string number_str = match.str(); std::string number_str = match.str();
numberVertices = std::stoi(number_str); numberVertices = std::stoi(number_str);
} } else {
else {
throw std::runtime_error("No number found in the input string."); throw std::runtime_error("No number found in the input string.");
} }
std::vector<Vector3f> vertices; std::vector <Vector3f> vertices;
vertices.resize(numberVertices); vertices.resize(numberVertices);
for (int i = 0; i < numberVertices; i++) for (int i = 0; i < numberVertices; i++) {
{
std::getline(f, tempLine); std::getline(f, tempLine);
std::vector<float> floatValues; std::vector<float> floatValues;
@ -68,7 +65,7 @@ namespace ZL
b = match.suffix().first; b = match.suffix().first;
} }
vertices[i] = Vector3f{ floatValues[0], floatValues[1], floatValues[2] }; vertices[i] = Vector3f{floatValues[0], floatValues[1], floatValues[2]};
} }
std::cout << "UV Coordinates" << std::endl; std::cout << "UV Coordinates" << std::endl;
@ -81,19 +78,17 @@ namespace ZL
if (std::regex_search(tempLine, match, pattern_count)) { if (std::regex_search(tempLine, match, pattern_count)) {
std::string number_str = match.str(); std::string number_str = match.str();
numberTriangles = std::stoi(number_str); numberTriangles = std::stoi(number_str);
} } else {
else {
throw std::runtime_error("No number found in the input string."); throw std::runtime_error("No number found in the input string.");
} }
// Now process UVs // Now process UVs
std::vector<std::array<Vector2f, 3>> uvCoords; std::vector <std::array<Vector2f, 3>> uvCoords;
uvCoords.resize(numberTriangles); uvCoords.resize(numberTriangles);
for (int i = 0; i < numberTriangles; i++) for (int i = 0; i < numberTriangles; i++) {
{
std::getline(f, tempLine); //Face 0 std::getline(f, tempLine); //Face 0
int uvCount; int uvCount;
@ -101,20 +96,17 @@ namespace ZL
if (std::regex_search(tempLine, match, pattern_count)) { if (std::regex_search(tempLine, match, pattern_count)) {
std::string number_str = match.str(); std::string number_str = match.str();
uvCount = std::stoi(number_str); uvCount = std::stoi(number_str);
} } else {
else {
throw std::runtime_error("No number found in the input string."); throw std::runtime_error("No number found in the input string.");
} }
if (uvCount != 3) if (uvCount != 3) {
{
throw std::runtime_error("more than 3 uvs"); throw std::runtime_error("more than 3 uvs");
} }
std::vector<float> floatValues; std::vector<float> floatValues;
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++) {
{
std::getline(f, tempLine); //UV <Vector (-0.3661, -1.1665)> std::getline(f, tempLine); //UV <Vector (-0.3661, -1.1665)>
auto b = tempLine.cbegin(); auto b = tempLine.cbegin();
@ -125,12 +117,11 @@ namespace ZL
b = match.suffix().first; b = match.suffix().first;
} }
if (floatValues.size() != 2) if (floatValues.size() != 2) {
{
throw std::runtime_error("more than 2 uvs---"); throw std::runtime_error("more than 2 uvs---");
} }
uvCoords[i][j] = Vector2f{ floatValues[0],floatValues[1] }; uvCoords[i][j] = Vector2f{floatValues[0], floatValues[1]};
} }
} }
@ -139,11 +130,10 @@ namespace ZL
std::getline(f, tempLine); //===Normals: std::getline(f, tempLine); //===Normals:
std::vector<Vector3f> normals; std::vector <Vector3f> normals;
normals.resize(numberVertices); normals.resize(numberVertices);
for (int i = 0; i < numberVertices; i++) for (int i = 0; i < numberVertices; i++) {
{
std::getline(f, tempLine); std::getline(f, tempLine);
std::vector<float> floatValues; std::vector<float> floatValues;
@ -155,7 +145,7 @@ namespace ZL
b = match.suffix().first; b = match.suffix().first;
} }
normals[i] = Vector3f{ floatValues[0], floatValues[1], floatValues[2] }; normals[i] = Vector3f{floatValues[0], floatValues[1], floatValues[2]};
} }
std::cout << "Triangles go:" << std::endl; std::cout << "Triangles go:" << std::endl;
@ -163,11 +153,10 @@ namespace ZL
std::getline(f, tempLine); //===Triangles: 3974 std::getline(f, tempLine); //===Triangles: 3974
std::vector<std::array<int, 3>> triangles; std::vector <std::array<int, 3>> triangles;
triangles.resize(numberTriangles); triangles.resize(numberTriangles);
for (int i = 0; i < numberTriangles; i++) for (int i = 0; i < numberTriangles; i++) {
{
std::getline(f, tempLine); std::getline(f, tempLine);
std::vector<int> intValues; std::vector<int> intValues;
@ -179,7 +168,7 @@ namespace ZL
b = match.suffix().first; b = match.suffix().first;
} }
triangles[i] = { intValues[0], intValues[1], intValues[2] }; triangles[i] = {intValues[0], intValues[1], intValues[2]};
} }
@ -189,8 +178,7 @@ namespace ZL
// Now let's process vertices // Now let's process vertices
for (int i = 0; i < numberTriangles; i++) for (int i = 0; i < numberTriangles; i++) {
{
result.PositionData.push_back(vertices[triangles[i][0]]); result.PositionData.push_back(vertices[triangles[i][0]]);
result.PositionData.push_back(vertices[triangles[i][1]]); result.PositionData.push_back(vertices[triangles[i][1]]);
@ -208,8 +196,7 @@ namespace ZL
} }
//Swap from Blender format to OpenGL format //Swap from Blender format to OpenGL format
for (int i = 0; i < result.PositionData.size(); i++) for (int i = 0; i < result.PositionData.size(); i++) {
{
Vector3f tempVec = result.PositionData[i]; Vector3f tempVec = result.PositionData[i];
result.PositionData[i].v[0] = tempVec.v[1]; result.PositionData[i].v[0] = tempVec.v[1];
result.PositionData[i].v[1] = tempVec.v[2]; result.PositionData[i].v[1] = tempVec.v[2];
@ -227,34 +214,50 @@ namespace ZL
} }
VertexDataStruct LoadFromTextFile02(const std::string& fileName, const std::string& ZIPFileName) VertexDataStruct
{ LoadFromTextFile02(const std::string &fileName, const std::string &ZIPFileName) {
VertexDataStruct result; VertexDataStruct result;
#ifdef __ANDROID__
// Для Android используем SDL_RWops для чтения файлов
__android_log_print(ANDROID_LOG_INFO, "TextModel",
"LoadFromTextFile02 called for Android: %s", fileName.c_str());
// Читаем файл с помощью readTextFile
std::string fileContent = readTextFile(fileName);
if (fileContent.empty()) {
__android_log_print(ANDROID_LOG_ERROR, "TextModel",
"Failed to read file: %s", fileName.c_str());
throw std::runtime_error("Failed to read file: " + fileName);
}
__android_log_print(ANDROID_LOG_INFO, "TextModel",
"File read successfully, size: %zu", fileContent.size());
std::istringstream f(fileContent);
#else
// Оригинальный код для десктопа
std::ifstream filestream; std::ifstream filestream;
std::istringstream zipStream; std::istringstream zipStream;
// --- 1. Открытие потока (без изменений) --- if (!ZIPFileName.empty()) {
if (!ZIPFileName.empty())
{
std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName); std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName);
std::string fileContents(fileData.begin(), fileData.end()); std::string fileContents(fileData.begin(), fileData.end());
zipStream.str(fileContents); zipStream.str(fileContents);
} f = static_cast<std::istream &>(zipStream);
else } else {
{
filestream.open(fileName); filestream.open(fileName);
if (!filestream.is_open()) { if (!filestream.is_open()) {
throw std::runtime_error("Failed to open file: " + fileName); throw std::runtime_error("Failed to open file: " + fileName);
} }
f = static_cast<std::istream &>(filestream);
} }
#endif
std::istream& f = (!ZIPFileName.empty()) ? static_cast<std::istream&>(zipStream) : static_cast<std::istream&>(filestream);
std::string tempLine; std::string tempLine;
std::smatch match; std::smatch match;
// Обновленные регулярки // Обновленные регулярки
// pattern_float стал чуть надежнее для чисел вида "0" или "-1" без точки, если вдруг Python округлит до int
static const std::regex pattern_count(R"(\d+)"); static const std::regex pattern_count(R"(\d+)");
static const std::regex pattern_float(R"([-]?\d+(\.\d+)?)"); static const std::regex pattern_float(R"([-]?\d+(\.\d+)?)");
static const std::regex pattern_int(R"([-]?\d+)"); static const std::regex pattern_int(R"([-]?\d+)");
@ -269,23 +272,21 @@ namespace ZL
int numberVertices = 0; int numberVertices = 0;
if (std::regex_search(tempLine, match, pattern_count)) { if (std::regex_search(tempLine, match, pattern_count)) {
numberVertices = std::stoi(match.str()); numberVertices = std::stoi(match.str());
} } else {
else {
throw std::runtime_error("Vertices header not found or invalid."); throw std::runtime_error("Vertices header not found or invalid.");
} }
// Временные буферы для хранения "уникальных" вершин перед разверткой по индексам // Временные буферы для хранения "уникальных" вершин перед разверткой по индексам
std::vector<Vector3f> tempPositions(numberVertices); std::vector <Vector3f> tempPositions(numberVertices);
std::vector<Vector3f> tempNormals(numberVertices); std::vector <Vector3f> tempNormals(numberVertices);
std::vector<Vector2f> tempUVs(numberVertices); std::vector <Vector2f> tempUVs(numberVertices);
for (int i = 0; i < numberVertices; i++) for (int i = 0; i < numberVertices; i++) {
{
std::getline(f, tempLine); std::getline(f, tempLine);
// Строка вида: V 0: Pos(x, y, z) Norm(x, y, z) UV(u, v) // Строка вида: V 0: Pos(x, y, z) Norm(x, y, z) UV(u, v)
std::vector<float> floatValues; std::vector<float> floatValues;
floatValues.reserve(8); // Ожидаем ровно 8 чисел (3 pos + 3 norm + 2 uv) floatValues.reserve(9); // ID + 3 pos + 3 norm + 2 uv
auto b = tempLine.cbegin(); auto b = tempLine.cbegin();
auto e = tempLine.cend(); auto e = tempLine.cend();
@ -294,23 +295,31 @@ namespace ZL
b = match.suffix().first; b = match.suffix().first;
} }
// Проверка целостности строки (ID вершины regex может поймать первым, но нас интересуют данные) // Проверка, что у нас достаточно данных
// Обычно ID идет первым (0), потом 3+3+2 float. Итого 9 чисел, если считать ID. if (floatValues.size() < 9) {
// Ваш Python пишет "V 0:", regex поймает 0. Потом 8 флоатов. #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_WARN, "TextModel",
"Warning: vertex line has only %zu values, expected 9",
floatValues.size());
#endif
// Попробуем с меньшим количеством, возможно данные упрощенные
if (floatValues.size() >= 8) {
// Без ID
tempPositions[i] = Vector3f{floatValues[0], floatValues[1], floatValues[2]};
tempNormals[i] = Vector3f{floatValues[3], floatValues[4], floatValues[5]};
tempUVs[i] = Vector2f{floatValues[6], floatValues[7]};
continue;
}
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i));
}
// Если regex ловит ID вершины как float (что вероятно), нам нужно смещение.
// ID - floatValues[0] // ID - floatValues[0]
// Pos - [1], [2], [3] // Pos - [1], [2], [3]
// Norm - [4], [5], [6] // Norm - [4], [5], [6]
// UV - [7], [8] // UV - [7], [8]
tempPositions[i] = Vector3f{floatValues[1], floatValues[2], floatValues[3]};
if (floatValues.size() < 9) { tempNormals[i] = Vector3f{floatValues[4], floatValues[5], floatValues[6]};
throw std::runtime_error("Malformed vertex line at index " + std::to_string(i)); tempUVs[i] = Vector2f{floatValues[7], floatValues[8]};
}
tempPositions[i] = Vector3f{ floatValues[1], floatValues[2], floatValues[3] };
tempNormals[i] = Vector3f{ floatValues[4], floatValues[5], floatValues[6] };
tempUVs[i] = Vector2f{ floatValues[7], floatValues[8] };
} }
// --- 3. Парсинг Треугольников (Индексов) --- // --- 3. Парсинг Треугольников (Индексов) ---
@ -323,8 +332,7 @@ namespace ZL
int numberTriangles = 0; int numberTriangles = 0;
if (std::regex_search(tempLine, match, pattern_count)) { if (std::regex_search(tempLine, match, pattern_count)) {
numberTriangles = std::stoi(match.str()); numberTriangles = std::stoi(match.str());
} } else {
else {
throw std::runtime_error("Triangles header not found."); throw std::runtime_error("Triangles header not found.");
} }
@ -333,8 +341,7 @@ namespace ZL
result.NormalData.reserve(numberTriangles * 3); result.NormalData.reserve(numberTriangles * 3);
result.TexCoordData.reserve(numberTriangles * 3); result.TexCoordData.reserve(numberTriangles * 3);
for (int i = 0; i < numberTriangles; i++) for (int i = 0; i < numberTriangles; i++) {
{
std::getline(f, tempLine); std::getline(f, tempLine);
// Строка вида: Tri: 0 1 2 // Строка вида: Tri: 0 1 2
@ -353,8 +360,6 @@ namespace ZL
} }
// --- 4. Заполнение VertexDataStruct (Flattening) --- // --- 4. Заполнение VertexDataStruct (Flattening) ---
// Берем данные из временных буферов по индексам и кладем в итоговый массив
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
int idx = indices[k]; int idx = indices[k];
result.PositionData.push_back(tempPositions[idx]); result.PositionData.push_back(tempPositions[idx]);
@ -364,10 +369,7 @@ namespace ZL
} }
// --- 5. Конвертация координат (Blender -> OpenGL/Engine) --- // --- 5. Конвертация координат (Blender -> OpenGL/Engine) ---
// Сохраняем вашу логику смены осей: X->Z, Y->X, Z->Y for (size_t i = 0; i < result.PositionData.size(); i++) {
for (size_t i = 0; i < result.PositionData.size(); i++)
{
Vector3f originalPos = result.PositionData[i]; Vector3f originalPos = result.PositionData[i];
result.PositionData[i].v[0] = originalPos.v[1]; // New X = Old Y result.PositionData[i].v[0] = originalPos.v[1]; // New X = Old Y
result.PositionData[i].v[1] = originalPos.v[2]; // New Y = Old Z result.PositionData[i].v[1] = originalPos.v[2]; // New Y = Old Z
@ -379,12 +381,17 @@ namespace ZL
result.NormalData[i].v[2] = originalNorm.v[0]; result.NormalData[i].v[2] = originalNorm.v[0];
} }
std::cout << "Model loaded: " << numberVertices << " verts, " << numberTriangles << " tris." << std::endl; #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO, "TextModel",
"Model loaded successfully: %d verts, %d tris",
numberVertices, numberTriangles);
#else
std::cout << "Model loaded: " << numberVertices << " verts, " << numberTriangles << " tris."
<< std::endl;
#endif
return result; return result;
} }
} }

View File

@ -5,8 +5,14 @@
#include <unordered_map> #include <unordered_map>
namespace ZL #ifdef __ANDROID__
{ #include <android/log.h>
VertexDataStruct LoadFromTextFile(const std::string& fileName, const std::string& ZIPFileName = ""); #endif
VertexDataStruct LoadFromTextFile02(const std::string& fileName, const std::string& ZIPFileName = "");
namespace ZL {
VertexDataStruct
LoadFromTextFile(const std::string &fileName, const std::string &ZIPFileName = "");
VertexDataStruct
LoadFromTextFile02(const std::string &fileName, const std::string &ZIPFileName = "");
} }

View File

@ -6,42 +6,92 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
//#include <zip.h> //#include <zip.h>
#include <SDL.h>
namespace ZL #ifdef __ANDROID__
{ #include <android/log.h>
#endif
std::string readTextFile(const std::string& filename) namespace ZL {
{ std::string readTextFile(const std::string &filename) {
#ifdef __ANDROID__
SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb");
if (!file) {
#ifdef DEBUG
__android_log_print(ANDROID_LOG_ERROR, "Utils",
"Failed to open: %s", filename.c_str());
#endif
return "";
}
Sint64 size = SDL_RWsize(file);
if (size <= 0) {
SDL_RWclose(file);
return "";
}
std::string content(size, '\0');
if (SDL_RWread(file, &content[0], size, 1) != 1) {
SDL_RWclose(file);
return "";
}
SDL_RWclose(file);
return content;
#else
std::ifstream f(filename); std::ifstream f(filename);
if (!f.is_open()) {
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); return "";
}
return str; return std::string((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());
#endif
} }
std::vector<char> readFile(const std::string& filename) std::vector<char> readFile(const std::string &filename) {
{ #ifdef __ANDROID__
std::ifstream file(filename, std::ios::binary); SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb");
if (!file) {
return {};
}
file.unsetf(std::ios::skipws); Sint64 size = SDL_RWsize(file);
if (size <= 0) {
SDL_RWclose(file);
return {};
}
std::streampos fileSize; std::vector<char> data(size);
if (SDL_RWread(file, data.data(), size, 1) != 1) {
SDL_RWclose(file);
return {};
}
SDL_RWclose(file);
return data;
#else
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file) {
return {};
}
std::streamsize size = file.tellg();
if (size <= 0) {
return {};
}
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
std::vector<char> buffer(size);
std::vector<char> vec; if (!file.read(buffer.data(), size)) {
vec.reserve(fileSize); return {};
vec.insert(vec.begin(),
std::istream_iterator<char>(file),
std::istream_iterator<char>());
return vec;
} }
std::vector<char> readFileFromZIP(const std::string& filename, const std::string& zipfilename) { return buffer;
#endif
}
std::vector<char> readFileFromZIP(const std::string &filename, const std::string &zipfilename) {
/*const std::string zipPath = zipfilename; /*const std::string zipPath = zipfilename;
int zipErr; int zipErr;
zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr); zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr);
@ -81,19 +131,13 @@ namespace ZL
return {}; return {};
} }
bool findString(const char* in, char* list) bool findString(const char *in, char *list) {
{
size_t thisLength = strlen(in); size_t thisLength = strlen(in);
while (*list != 0) while (*list != 0) {
{
size_t length = strcspn(list, " "); size_t length = strcspn(list, " ");
if (thisLength == length && !strncmp(in, list, length))
if (thisLength == length)
if (!strncmp(in, list, length))
return true; return true;
list += length + 1;
list += length;
list += 1;
} }
return false; return false;
} }

View File

@ -1,25 +1,48 @@
#include "Game.h" #include "Game.h"
#include "Environment.h" #include "Environment.h"
#ifdef __ANDROID__
#include <android/log.h>
#endif
ZL::Game game; ZL::Game game;
#ifdef __ANDROID__ #ifdef __ANDROID__
extern "C" int SDL_main(int argc, char* argv[]) { extern "C" int SDL_main(int argc, char* argv[]) {
#else #else
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
#endif #endif
#ifdef __ANDROID__ #ifdef __ANDROID__
// Инициализация SDL перед получением информации о дисплее
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL init failed: %s", SDL_GetError());
return 1;
}
SDL_DisplayMode displayMode; SDL_DisplayMode displayMode;
SDL_GetCurrentDisplayMode(0, &displayMode); if (SDL_GetCurrentDisplayMode(0, &displayMode) != 0) {
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GetCurrentDisplayMode failed: %s", SDL_GetError());
SDL_Quit();
return 1;
}
ZL::Environment::width = displayMode.w; ZL::Environment::width = displayMode.w;
ZL::Environment::height = displayMode.h; ZL::Environment::height = displayMode.h;
__android_log_print(ANDROID_LOG_INFO, "Game", "Display resolution: %dx%d",
ZL::Environment::width, ZL::Environment::height);
#else #else
constexpr int CONST_WIDTH = 1280; constexpr int CONST_WIDTH = 1280;
constexpr int CONST_HEIGHT = 720; constexpr int CONST_HEIGHT = 720;
ZL::Environment::width = CONST_WIDTH; ZL::Environment::width = CONST_WIDTH;
ZL::Environment::height = CONST_HEIGHT; ZL::Environment::height = CONST_HEIGHT;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
SDL_Log("SDL init failed: %s", SDL_GetError());
return 1;
}
#endif #endif
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
@ -52,15 +75,18 @@ int main(int argc, char* argv[]) {
ZL::Environment::window = win; ZL::Environment::window = win;
#else #else
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
SDL_Log("SDL init failed: %s", SDL_GetError());
return 1;
}
#ifdef __ANDROID__ #ifdef __ANDROID__
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
ZL::Environment::window = SDL_CreateWindow( ZL::Environment::window = SDL_CreateWindow(
"Space Ship Game", "Space Ship Game",
@ -69,9 +95,12 @@ int main(int argc, char* argv[]) {
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
); );
#else #else
// Для десктопа
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
ZL::Environment::window = SDL_CreateWindow( ZL::Environment::window = SDL_CreateWindow(
"Space Ship Game", "Space Ship Game",
@ -81,11 +110,63 @@ int main(int argc, char* argv[]) {
); );
#endif #endif
SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window); if (!ZL::Environment::window) {
SDL_GL_MakeCurrent(ZL::Environment::window, ctx); #ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game", "Failed to create window: %s", SDL_GetError());
#else
SDL_Log("Failed to create window: %s", SDL_GetError());
#endif
SDL_Quit();
return 1;
}
#ifdef __ANDROID__
#endif #endif
SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window);
if (!ctx) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GL_CreateContext failed: %s", SDL_GetError());
#else
SDL_Log("SDL_GL_CreateContext failed: %s", SDL_GetError());
#endif
SDL_DestroyWindow(ZL::Environment::window);
SDL_Quit();
return 1;
}
if (SDL_GL_MakeCurrent(ZL::Environment::window, ctx) != 0) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GL_MakeCurrent failed: %s", SDL_GetError());
#else
SDL_Log("SDL_GL_MakeCurrent failed: %s", SDL_GetError());
#endif
SDL_GL_DeleteContext(ctx);
SDL_DestroyWindow(ZL::Environment::window);
SDL_Quit();
return 1;
}
// Настройка VSync
if (SDL_GL_SetSwapInterval(1) < 0) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_WARN, "Game", "Unable to set VSync: %s", SDL_GetError());
#endif
}
#endif
// Настройка игры
try {
game.setup(); game.setup();
} catch (const std::exception &e) {
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_ERROR, "Game", "Game setup failed: %s", e.what());
#else
std::cerr << "Game setup failed: " << e.what() << std::endl;
#endif
return 1;
}
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
emscripten_set_main_loop(MainLoop, 0, 1); emscripten_set_main_loop(MainLoop, 0, 1);

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -1,8 +1,7 @@
#version 100
precision mediump float; precision mediump float;
varying vec3 color;
varying vec3 fragmentColor; void main()
{
void main(void) { gl_FragColor = vec4(color, 1.0);
gl_FragColor = vec4(fragmentColor, 1.0);
} }

View File

@ -1,9 +1,9 @@
#version 100
precision mediump float; precision mediump float;
varying vec2 TexCoordOut;
uniform sampler2D Texture; uniform sampler2D Texture;
varying vec2 texCoord;
void main(void) { void main()
gl_FragColor = texture2D(Texture, TexCoordOut); {
vec4 color = texture2D(Texture, texCoord);
gl_FragColor = color;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB