Convert sharing test to GL2

This commit is contained in:
Camilla Berglund 2016-09-20 14:12:15 +02:00
parent f7584bf14c
commit ca38af0d83

View File

@ -33,11 +33,34 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define WIDTH 400 #include "linmath.h"
#define HEIGHT 400
#define OFFSET 50
static GLFWwindow* windows[2]; static const char* vertex_shader_text =
"uniform mat4 MVP;\n"
"attribute vec2 vPos;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
" texcoord = vPos;\n"
"}\n";
static const char* fragment_shader_text =
"uniform sampler2D texture;\n"
"uniform vec3 color;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(color * tex2D(texture, texcoord).rgb, 1.0);\n"
"}\n";
static const vec2 vertices[4] =
{
{ 0.f, 0.f },
{ 1.f, 0.f },
{ 1.f, 1.f },
{ 0.f, 1.f }
};
static void error_callback(int error, const char* description) static void error_callback(int error, const char* description)
{ {
@ -50,31 +73,45 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
glfwSetWindowShouldClose(window, GLFW_TRUE); glfwSetWindowShouldClose(window, GLFW_TRUE);
} }
static GLFWwindow* open_window(const char* title, GLFWwindow* share, int posX, int posY) int main(int argc, char** argv)
{ {
GLFWwindow* window; GLFWwindow* windows[2];
GLuint texture, vertex_shader, fragment_shader, program, vertex_buffer;
GLint mvp_location, vpos_location, color_location, texture_location;
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwSetErrorCallback(error_callback);
window = glfwCreateWindow(WIDTH, HEIGHT, title, NULL, share);
if (!window)
return NULL;
glfwMakeContextCurrent(window); if (!glfwInit())
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); exit(EXIT_FAILURE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
windows[0] = glfwCreateWindow(400, 400, "First", NULL, NULL);
if (!windows[0])
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetKeyCallback(windows[0], key_callback);
glfwMakeContextCurrent(windows[0]);
// Only enable vsync for the first of the windows to be swapped to
// avoid waiting out the interval for each window
glfwSwapInterval(1); glfwSwapInterval(1);
glfwSetWindowPos(window, posX, posY);
glfwShowWindow(window);
glfwSetKeyCallback(window, key_callback); // The contexts are created with the same APIs so the function
// pointers should be re-usable between them
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
return window; // Create the OpenGL objects inside the first context, created above
} // All objects will be shared with the second context, created below
{
static GLuint create_texture(void)
{
int x, y; int x, y;
char pixels[256 * 256]; char pixels[256 * 256];
GLuint texture; GLuint vertex_shader, fragment_shader;
glGenTextures(1, &texture); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
@ -89,93 +126,102 @@ static GLuint create_texture(void)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return texture; vertex_shader = glCreateShader(GL_VERTEX_SHADER);
} glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(vertex_shader);
static void draw_quad(GLuint texture) fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
{ glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
int width, height; glCompileShader(fragment_shader);
glfwGetFramebufferSize(glfwGetCurrentContext(), &width, &height);
glViewport(0, 0, width, height); program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glMatrixMode(GL_PROJECTION); mvp_location = glGetUniformLocation(program, "MVP");
glLoadIdentity(); color_location = glGetUniformLocation(program, "color");
glOrtho(0.f, 1.f, 0.f, 1.f, 0.f, 1.f); texture_location = glGetUniformLocation(program, "texture");
vpos_location = glGetAttribLocation(program, "vPos");
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
glUseProgram(program);
glUniform1i(texture_location, 0);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBegin(GL_QUADS); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glEnableVertexAttribArray(vpos_location);
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
sizeof(vertices[0]), (void*) 0);
glTexCoord2f(0.f, 0.f); windows[1] = glfwCreateWindow(400, 400, "Second", NULL, windows[0]);
glVertex2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f);
glVertex2f(1.f, 0.f);
glTexCoord2f(1.f, 1.f);
glVertex2f(1.f, 1.f);
glTexCoord2f(0.f, 1.f);
glVertex2f(0.f, 1.f);
glEnd();
}
int main(int argc, char** argv)
{
int x, y, width;
GLuint texture;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
windows[0] = open_window("First", NULL, OFFSET, OFFSET);
if (!windows[0])
{
glfwTerminate();
exit(EXIT_FAILURE);
}
// This is the one and only time we create a texture
// It is created inside the first context, created above
// It will then be shared with the second context, created below
texture = create_texture();
glfwGetWindowPos(windows[0], &x, &y);
glfwGetWindowSize(windows[0], &width, NULL);
// Put the second window to the right of the first one
windows[1] = open_window("Second", windows[0], x + width + OFFSET, y);
if (!windows[1]) if (!windows[1])
{ {
glfwTerminate(); glfwTerminate();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Set drawing color for both contexts // Place the second window to the right of the first
glfwMakeContextCurrent(windows[0]); {
glColor3f(0.6f, 0.f, 0.6f); int xpos, ypos, left, right, width;
glfwMakeContextCurrent(windows[1]);
glColor3f(0.6f, 0.6f, 0.f);
glfwMakeContextCurrent(windows[0]); glfwGetWindowSize(windows[0], &width, NULL);
glfwGetWindowFrameSize(windows[0], &left, NULL, &right, NULL);
glfwGetWindowPos(windows[0], &xpos, &ypos);
glfwSetWindowPos(windows[1], xpos + width + left + right, ypos);
}
glfwSetKeyCallback(windows[1], key_callback);
glfwMakeContextCurrent(windows[1]);
// While objects are shared, the global context state is not and will
// need to be set up for each context
glUseProgram(program);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glEnableVertexAttribArray(vpos_location);
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
sizeof(vertices[0]), (void*) 0);
while (!glfwWindowShouldClose(windows[0]) && while (!glfwWindowShouldClose(windows[0]) &&
!glfwWindowShouldClose(windows[1])) !glfwWindowShouldClose(windows[1]))
{ {
glfwMakeContextCurrent(windows[0]); int i;
draw_quad(texture); const vec3 colors[2] =
{
{ 0.6f, 0.6f, 0.f },
{ 0.6f, 0.f, 0.6f }
};
glfwMakeContextCurrent(windows[1]); for (i = 0; i < 2; i++)
draw_quad(texture); {
int width, height;
mat4x4 mvp;
glfwSwapBuffers(windows[0]); glfwGetFramebufferSize(windows[i], &width, &height);
glfwSwapBuffers(windows[1]); glfwMakeContextCurrent(windows[i]);
glViewport(0, 0, width, height);
mat4x4_ortho(mvp, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f);
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
glUniform3fv(color_location, 1, colors[i]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glfwSwapBuffers(windows[i]);
}
glfwWaitEvents(); glfwWaitEvents();
} }