Commits

Marc Lepage committed 7f10e42 Draft

Add shaders for drawing image.

Comments (0)

Files changed (3)

src/modules/graphics/opengl/GLES.cpp

 // LOVE
 #include "common/Matrix.h"
 
+// OpenGL
+#include <GLES2/gl2.h>
+
 // STD
+#include <cstdio>
 #include <cstring> // memcpy
 #include <vector>
 
 namespace
 {
 
+GLuint drawQuadProgram;
+
 float color[4] = { 1, 1, 1, 1 };
 
 // Modes: 0=modelview, 1=projection, 2=color, 3=texture
 
 int mode = init(); // easy way to initialize
 
+GLuint loadShader(GLenum shaderType, const char* shaderSrc)
+{
+	GLuint shader = glCreateShader(shaderType);
+	if (!shader)
+	{
+		fprintf(stderr, "no shader love :-(\n");
+		return 0;
+	}
+
+	glShaderSource(shader, 1, &shaderSrc, NULL);
+
+	glCompileShader(shader);
+
+	GLint compiled;
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+
+	if (!compiled)
+	{
+		char infoLog[1024];
+		glGetShaderInfoLog(shader, 1024, NULL, infoLog);
+		fprintf(stderr, "shader failed to compile: %s\n", infoLog);
+		glDeleteShader(shader);
+		return 0;
+	}
+
+	return shader;
+}
+
+GLuint loadProgram(const char* vertexShaderSrc, const char* fragmentShaderSrc)
+{
+	GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderSrc);
+	if (!vertexShader)
+	{
+		return 0;
+	}
+
+	GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderSrc);
+	if (!fragmentShader)
+	{
+		glDeleteShader(vertexShader);
+		return 0;
+	}
+	
+	GLuint program = glCreateProgram();
+	if (!program)
+	{
+		fprintf(stderr, "no program love :-(\n");
+		glDeleteShader(vertexShader);
+		glDeleteShader(fragmentShader);
+		return 0;
+	}
+
+	glAttachShader(program, vertexShader);
+	glAttachShader(program, fragmentShader);
+
+	glLinkProgram(program);
+
+	glDeleteShader(vertexShader);
+	glDeleteShader(fragmentShader);
+
+	GLint linked;
+	glGetProgramiv(program, GL_LINK_STATUS, &linked);
+
+	if (!linked)
+	{
+		char infoLog[1024];
+		glGetProgramInfoLog(program, 1024, NULL, infoLog);
+		fprintf(stderr, "program failed to link: %s\n", infoLog);
+		glDeleteProgram(program);
+		return 0;
+	}
+
+	return program;
+}
+
 } // namespace
 
 extern "C"
 	// TODO
 }
 
+void glesDrawQuad(int vstride, const float* vdata, int tstride, const float* tdata)
+{
+	static GLubyte indices[] = { 0, 1, 3, 2 };
+	static GLuint program = 0;
+	static GLint locP, locM, locS, locV, locT;
+
+	// TODO add support for color modulation
+
+	if (!program)
+	{
+		program = loadProgram(
+		"    uniform mat4 u_matProjection;                                     \n"
+		"    uniform mat4 u_matModelView;                                      \n"
+		"    attribute vec4 a_position;                                        \n"
+		"    attribute vec2 a_texCoord;                                        \n"
+		"    varying vec2 v_texCoord;                                          \n"
+		"    void main()                                                       \n"
+		"    {                                                                 \n"
+		"        gl_Position = u_matProjection * u_matModelView * a_position;  \n"
+		"        v_texCoord = a_texCoord;                                      \n"
+		"    }                                                                 \n",
+
+		"    varying vec2 v_texCoord;                               \n"
+		"    uniform sampler2D s_texture;                           \n"
+		"    void main()                                            \n"
+		"    {                                                      \n"
+		"        gl_FragColor = texture2D(s_texture, v_texCoord);   \n"
+		"    }                                                      \n");
+
+		locP = glGetUniformLocation(program, "u_matProjection");
+		locM = glGetUniformLocation(program, "u_matModelView");
+		locS = glGetUniformLocation(program, "s_texture");
+		locV = glGetAttribLocation(program, "a_position");
+		locT = glGetAttribLocation(program, "a_texCoord");
+	}
+
+	glUseProgram(program);
+
+	glUniformMatrix4fv(locP, 1, GL_FALSE, stack[1].back().getElements());
+	glUniformMatrix4fv(locM, 1, GL_FALSE, stack[0].back().getElements());
+
+	glUniform1i(locS, 0);
+
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+
+	glVertexAttribPointer(locV, 2, GL_FLOAT, GL_FALSE, vstride, vdata);
+	glVertexAttribPointer(locT, 2, GL_FLOAT, GL_FALSE, tstride, tdata);
+
+	glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
+
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
+}
+
 } // extern "C"
 
 #endif // HAVE_GLES

src/modules/graphics/opengl/GLES.h

 void glPushAttrib(unsigned int mask);
 void glPopAttrib(void);
 
+void glesDrawQuad(int vstride, const float* vdata, int tstride, const float* tdata);
+
 }
 
 #endif // HAVE_GLES

src/modules/graphics/opengl/Image.cpp

 	vertices[2].s = s;
 	vertices[3].s = s;
 
-#if !defined(HAVE_GLES)
 	glTexImage2D(GL_TEXTURE_2D,
 				 0,
-				 GL_RGBA8,
+				 GL_RGBA,
 				 (GLsizei)p2width,
 				 (GLsizei)p2height,
 				 0,
 				 GL_RGBA,
 				 GL_UNSIGNED_BYTE,
 				 0);
-#endif
 
 	glTexSubImage2D(GL_TEXTURE_2D,
 					0,
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-#if !defined(HAVE_GLES)
 	glTexImage2D(GL_TEXTURE_2D,
 				 0,
-				 GL_RGBA8,
+				 GL_RGBA,
 				 (GLsizei)width,
 				 (GLsizei)height,
 				 0,
 				 GL_RGBA,
 				 GL_UNSIGNED_BYTE,
 				 data->getData());
-#endif
 
 	setFilter(settings.filter);
 	setWrap(settings.wrap);
 	glDrawArrays(GL_QUADS, 0, 4);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 	glDisableClientState(GL_VERTEX_ARRAY);
+#else
+	glesDrawQuad(sizeof(vertex), &v[0].x, sizeof(vertex), &v[0].s);
 #endif
 
 	glPopMatrix();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.