File: test_sdl2_gldrawelements.c

package info (click to toggle)
emscripten 3.1.69%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 121,872 kB
  • sloc: ansic: 636,110; cpp: 425,974; javascript: 78,401; python: 58,404; sh: 49,154; pascal: 5,237; makefile: 3,365; asm: 2,415; lisp: 1,869
file content (169 lines) | stat: -rw-r--r-- 5,086 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*******************************************************************
 *                                                                 *
 *                        Using SDL With OpenGL                    *
 *                                                                 *
 *                    Tutorial by Kyle Foley (sdw)                 *
 *                                                                 *
 * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
 *                                                                 *
 *******************************************************************/

/*
THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.

THE ORIGINAL AUTHOR IS KYLE FOLEY.

THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
RESULTING FROM THE USE, MODIFICATION, OR
REDISTRIBUTION OF THIS SOFTWARE.
*/

#include "SDL.h"
#include "SDL_opengl.h"

#include <stdio.h>
#include <string.h>

#define WIDTH 640
#define HEIGHT 480

int main(int argc, char* argv[]) {
  SDL_Window* window;
  SDL_GLContext context;

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

  window = SDL_CreateWindow(
    "OpenGL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
  if (!window) {
    fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
    return 0;
  }

  context = SDL_GL_CreateContext(window);
  if (!context) {
    fprintf(stderr, "Couldn't create context: %s\n", SDL_GetError());
    return 0;
  }

  glMatrixMode(GL_PROJECTION);
  glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
  glMatrixMode(GL_MODELVIEW);

  glClearColor(0, 0, 0, 1);

  glEnable(GL_TEXTURE_2D);

  GLuint texture; // Texture object handle

  // Have OpenGL generate a texture object handle for us
  glGenTextures(1, &texture);

  // Bind the texture object
  glBindTexture(GL_TEXTURE_2D, texture);

  // Set the texture's stretching properties
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  GLubyte texture_data[] = {
    0xffu, 0x00u, 0x00u, 0xffu, // 0.0 0.0
    0x00u, 0xffu, 0x00u, 0xffu, // 1.0 0.0
    0x00u, 0x00u, 0xffu, 0xffu, // 0.0 1.0
    0xffu, 0xffu, 0x00u, 0xffu  // 1.0 1.0
  };

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);

  // Clear the screen before drawing
  glClear(GL_COLOR_BUFFER_BIT);

  // Bind the texture to which subsequent calls refer to
  glBindTexture(GL_TEXTURE_2D, texture);

  const GLenum modes[8] = {
    GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP,
    GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS
  };

  const GLfloat vertex_data[4][4] = {
    { 0.25f, 0.75f, 0.0f, 0.0f },
    { 0.25f, 0.25f, 1.0f, 0.0f },
    { 0.75f, 0.75f, 0.0f, 1.0f },
    { 0.75f, 0.25f, 1.0f, 1.0f }
  };

  const GLushort indices[] = {
    // GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLE_STRIP
    0u, 1u, 2u, 3u,
    // GL_TRIANGLES
    0u, 1u, 2u, 2u, 1u, 3u,
    // GL_TRIANGLE_FAN, GL_QUADS
    0u, 1u, 3u, 2u,
  };

  glVertexPointer(2, GL_FLOAT, sizeof (vertex_data[0]), &vertex_data[0][0]);
  glTexCoordPointer(2, GL_FLOAT, sizeof (vertex_data[0]), &vertex_data[0][2]);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  #define ROWS 2
  #define COLS 4
  #define PORT_W (WIDTH / COLS)
  #define PORT_H (HEIGHT / ROWS)

  for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLS; j++) {
      GLenum mode = modes[i * COLS + j];

      if (mode == GL_QUADS)
        continue;

      glViewport(j * PORT_W, i * PORT_H, PORT_W, PORT_H);

      if (mode == GL_TRIANGLE_FAN /* || mode == GL_QUADS*/)
        glDrawElements(mode, 4, GL_UNSIGNED_SHORT, &indices[10]);
      else if (mode == GL_TRIANGLES)
        glDrawElements(mode, 6, GL_UNSIGNED_SHORT, &indices[4]);
      else
        glDrawElements(mode, 4, GL_UNSIGNED_SHORT, &indices[0]);
    }
  }

  SDL_GL_SwapWindow(window);

#ifndef __EMSCRIPTEN__
  SDL_Event e;

  while (SDL_WaitEvent(&e)) {
    if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_F12) {
      void *pixels = malloc(WIDTH * HEIGHT * 3);
      if (pixels) {
        glReadBuffer(GL_FRONT);
        glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
        SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, WIDTH, HEIGHT, 32, WIDTH * 3, SDL_PIXELFORMAT_RGB24);
        if (surface) {
          SDL_SaveBMP(surface, "sdl2_gldrawelements.bmp");
        }
      }
    }
    if (e.type == SDL_QUIT)
      break;
  }
#endif

  // Now we can delete the OpenGL texture and close down SDL
  glDeleteTextures(1, &texture);

  // Don't quit - we need to reftest the canvas! SDL_Quit();

  return 0;
}