// #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ #include #include #include #include #if defined(__ANDROID__) #define APP_MAIN SDL_main #define SDL_WINDOW_FLAG SDL_WINDOW_FULLSCREEN #else #define APP_MAIN main #define SDL_WINDOW_FLAG 0 #endif #define SCREEN_WIDTH 1600 #define SCREEN_HEIGHT 720 #define BOX_WIDTH 250 #define BOX_HEIGHT 250 static SDL_Window *window = NULL; static bool running = true; static Uint8 color = 0x18; static Uint64 elapsed = 0; static float boxX = 0.f; static float boxY = 0.f; static float boxVelX = 1.f; static float boxVelY = 1.f; static float boxSpeed = 250.f; const char* vShader = "#version 300 es\n" "layout (location = 0) in vec2 aPos;\n" "uniform mat4 uTransform;\n" "void main()\n" "{\n" " gl_Position = uTransform * vec4(aPos, 0.0, 1.0);\n" "}"; const char* fShader = "#version 300 es\n" "precision mediump float;\n" "out vec4 FragColor;\n" "void main()\n" "{\n" " FragColor = vec4(1.0, 0.2, 0.3, 1.0); // red-ish\n" "}"; void makeRotationZ(float angle, float* m) { float c = cosf(angle); float s = sinf(angle); // column-major (OpenGL style) m[0] = c; m[4] = -s; m[8] = 0; m[12] = 0; m[1] = s; m[5] = c; m[9] = 0; m[13] = 0; m[2] = 0; m[6] = 0; m[10] = 1; m[14] = 0; m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1; } extern "C" int APP_MAIN(int argc, char **argv) { SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives"); SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight"); if (!SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); return SDL_APP_FAILURE; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); window = SDL_CreateWindow("examples/renderer/primitives", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_FLAG | SDL_WINDOW_OPENGL); if (!window) { SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); return SDL_APP_FAILURE; } SDL_GLContext glContext = SDL_GL_CreateContext(window); int success; char infoLog[512]; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vShader, NULL); glCompileShader(vertexShader); // print compile errors if any glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s\n", infoLog); }; GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fShader, NULL); glCompileShader(fragmentShader); // print compile errors if any glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s\n", infoLog); }; GLuint program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); // print linking errors if any glGetProgramiv(program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(program, 512, NULL, infoLog); printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n%s\n", infoLog); } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); float vertices[] = { // positions (x, y) -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f}; GLuint vao, vbo; glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); glEnable(GL_DEPTH_TEST); float transform[16]; while (running) { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_EVENT_QUIT) { running = false; } } auto now = SDL_GetTicks(); float dt = now - elapsed; elapsed = now; // SDL_Log("dt: %f\n", dt); dt /= 1000.f; boxX += boxSpeed * boxVelX * dt; boxY += boxSpeed * boxVelY * dt; boxSpeed += 50.f * dt; if (boxX + BOX_WIDTH >= SCREEN_WIDTH || boxX <= 0) boxVelX *= -1.f; if (boxY + BOX_HEIGHT >= SCREEN_HEIGHT || boxY <= 0) boxVelY *= -1.f; glClearColor(0x18/255.f, 0x18/255.f, 0x18/255.f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw your 3D stuff here float angle = SDL_GetTicks() / 1000.0f; // rotates over time float transform[16]; makeRotationZ(angle, transform); GLuint loc = glGetUniformLocation(program, "uTransform"); glUseProgram(program); glUniformMatrix4fv(loc, 1, GL_FALSE, transform); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 6); SDL_GL_SwapWindow(window); } return 0; }