OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图
读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了
代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退出也会First-chance exception
glTexParameterf写错成glTextureParameteri
随手来个链接https://www.opengl.org/sdk/docs/man/html/glTexParameter.xhtml
//
// 绘制一个旋转的OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用
// 使用空闲回调函数增加旋转的角度
// 立方体的旋转角度被发送到用于实现立方体旋转的顶点着色器中 #include "Angel.h"
#pragma comment(lib, "glew32.lib") typedef Angel::vec4 color4;
typedef Angel::vec4 point4; const int NumVertices = ; //(6 faces)(2 triangles/face)(3 vertices/triangle) point4 points[NumVertices];
vec3 normals[NumVertices];//法向量标记 // Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[] = {
point4(-0.5, -0.5, 0.5, 1.0),
point4(-0.5, 0.5, 0.5, 1.0),
point4(0.5, 0.5, 0.5, 1.0),
point4(0.5, -0.5, 0.5, 1.0),
point4(-0.5, -0.5, -0.5, 1.0),
point4(-0.5, 0.5, -0.5, 1.0),
point4(0.5, 0.5, -0.5, 1.0),
point4(0.5, -0.5, -0.5, 1.0)
}; const int texturesize = ; //新增或有更改
GLuint textureloc;//新增或有更改
GLubyte imageRBG[texturesize][texturesize][];//新增或有更改
vec2 tex_coords[NumVertices];//新增或有更改 void imageinit()//新增或有更改
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
GLubyte c = (((i & 0x8) == ) ^ ((j & 0x8) == ) )*;
imageRBG[i][j][] = imageRBG[i][j][] = imageRBG[i][j][] = c;
}
}
glGenTextures(, &textureloc);//产生一个纹理对象标志符并存在地址textureloc中 glBindTexture(GL_TEXTURE_2D, textureloc);
glTexImage2D(GL_TEXTURE_2D, , GL_RGB, texturesize, texturesize, , GL_RGB, GL_UNSIGNED_BYTE, imageRBG);
//target90FL_TEXTURE_[1,2,3]D或者GL_TEXTURE_CUBE_MAP;level,iformat,width,height,border,format,type,&textureeloc; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//写错成glTextureParameteri
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureloc); }//新增或有更改 // Array of rotation angles (in degrees) for each coordinate axis
//enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
//enum { Xdist = 0, Ydist = 1, Zdist = 2, NumAxes1 = 3 };
color4 gr = color4(1.0, 1.0, 1.0, 1.0);
color4 onecolor = color4(1.0, 0.0, 0.0, 1.0);
color4 light_ex;
int Axi = ;//Xaxis;
GLfloat Thet[] = { 0.0, 0.0, 0.0 };
//GLfloat Atha[3] = { 0.0, 0.0, 0.0 };
GLfloat Disx = ;
GLfloat Dis = ;
GLfloat fd = ; GLuint thet; // The location of the "theta" shader uniform variable
GLuint atha;
GLuint direct;
GLuint f;
GLuint vam;
//---------------------------------------------------------------------------- // quad generates two triangles for each face and assigns colors
// to the vertices
int Index = ;
void
quad(int a, int b, int c, int d)
{
vec4 u = vertices[b] - vertices[a];
vec4 v = vertices[c] - vertices[b];
vec3 normal = normalize(cross(u, v));//normalize叉乘得到法向量
normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改
normals[Index] = normal; points[Index] = vertices[b]; tex_coords[Index] = vec2(0.0, 1.0); Index++;////新增或有更改
normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改
normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改
normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改
normals[Index] = normal; points[Index] = vertices[d]; tex_coords[Index] = vec2(1.0, 0.0); Index++;////新增或有更改
} //---------------------------------------------------------------------------- // generate 12 triangles: 36 vertices and 36 colors
void
colorcube()
{
quad(, , , );
quad(, , , );
quad(, , , );
quad(, , , );
quad(, , , );
quad(, , , );
} //---------------------------------------------------------------------------- // OpenGL initialization
void
init()
{
colorcube();//新增或有更改
imageinit();//新增或有更改 // Create a vertex array object
GLuint vao;
glGenVertexArrays(, &vao);
glBindVertexArray(vao); // Create and initialize a buffer object
GLuint buffer;
glGenBuffers(, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals) + sizeof(tex_coords), NULL, GL_STATIC_DRAW);// glBufferSubData(GL_ARRAY_BUFFER, , sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(normals), normals);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals), sizeof(tex_coords), tex_coords);//新增或有更改 // Load shaders and use the resulting shader program
GLuint program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program); // set up vertex arrays
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, , GL_FLOAT, GL_FALSE, ,BUFFER_OFFSET()); GLuint vNormal = glGetAttribLocation(program, "vNormal");
glEnableVertexAttribArray(vNormal);
glVertexAttribPointer(vNormal, , GL_FLOAT, GL_FALSE, , BUFFER_OFFSET(sizeof(points))); GLuint vTexCoord = glGetAttribLocation(program, "vtexCoord");////新增或有更改
glEnableVertexAttribArray(vTexCoord);////新增或有更改
glVertexAttribPointer(vTexCoord, , GL_FLOAT, GL_FALSE, , BUFFER_OFFSET(sizeof(points) + sizeof(normals)));////新增或有更改 //初始化光照参数la,ld,ls环境,漫反射,镜面反射
point4 light_position(0.0, 0.0, 2.0,-0.0);
//color4 light_ambient(1.0,0.0,0.0,1.0);//R红_G绿_B蓝
color4 light_diffuse(1.0, 1.0, 1.0, 1.0);
color4 light_specular(1.0, 1.0, 1.0, 1.0); color4 material_ambient(1.0, 0.0, 1.0, 1.0);
color4 material_diffuse(1.0, 0.8, 0.0, 1.0);
color4 material_specular(1.0, 0.8, 0.0, 1.0);
float material_shininess = 20.0;//高光系数 高金属 低塑料 light_ex = material_ambient;
//color4 ambient_product = light_ambient*material_ambient;
color4 diffuse_product = light_diffuse*material_diffuse;
color4 specular_product = light_specular*material_specular; glUniform4fv(glGetUniformLocation(program, "DiffuseProduct"), , diffuse_product);
glUniform4fv(glGetUniformLocation(program, "SpecularProduct"), , specular_product);
glUniform4fv(glGetUniformLocation(program, "LightPosition"), , light_position);
glUniform1f(glGetUniformLocation(program,"Shininess"),material_shininess); vam = glGetUniformLocation(program, "AmbientProduct");
thet = glGetUniformLocation(program, "theta");
atha = glGetUniformLocation(program, "athat");
direct = glGetUniformLocation(program, "direct");
f = glGetUniformLocation(program, "ff"); glUniform1i(glGetUniformLocation(program, "texture"), );//新增或有更改
//texture在vshader里面,后面的1对应glActiveTexture(GL_TEXTURE1);
//如果0,那么对应glActiveTexture(GL_TEXTURE0);
//如果3,那么对应glActiveTexture(GL_TEXTURE3); glEnable(GL_DEPTH_TEST);///开启深度缓存测试
glEnable(GL_CULL_FACE);///启动多边形剔除功能 //glOrtho(1.0, 0.0, 0.0, 1.0, 0.0, 1.0); } //---------------------------------------------------------------------------- void
display(void)
{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glMatrixMode(GL_PROJECTION);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
//gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0);
glUniform4fv(vam, , light_ex*onecolor);
glUniform3fv(thet, , Thet);
glUniform1f(atha, Disx);
glUniform1f(direct, Dis);//传递单个的
glUniform1f(f, fd);
glDrawArrays(GL_TRIANGLES, , NumVertices);
glClearColor(gr[], gr[], gr[], gr[]);
glFlush();
} void ProcessMenu(int value)
{
if (value == )
exit(); if (value == )
{
gr = vec4(1.0f, 1.0f, 1.0f, 1.0f);
onecolor = vec4(1.0, 0.0, 1.0, 1.0);
}
else{ switch (value)
{
case :gr = vec4(0.75f, 0.0f, 1.0f, 1.0f); break;
case :gr = vec4(0.75f, 0.75f, 1.0f, 1.0f); break;
case :gr = vec4(1.75f, 1.75f, 0.75f, 1.0f); break;
case :gr = vec4(1.75f, 1.0f, 1.55f, 1.0f); break;
case :gr = vec4(0.0f, 1.0f, 0.75f, 0.0f); break;
case :onecolor = color4(0.0, 0.0, 0.0, 1.0); break;//黑色
case :onecolor = color4(0.0, 0.0, 1.0, 1.0); break;//蓝色
case :onecolor = color4(1.0, 0.0, 1.0, 1.0); break;//品红色
case :onecolor = color4(0.0, 1.0, 1.0, 1.0); break;//青色
}
}
glutSwapBuffers();
glutPostRedisplay();
} //---------------------------------------------------------------------------- void
keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'x': Axi = ; break; //Xaxis; break;
case 'y': Axi = ; break;//Yaxis; break;
case 'z': Axi = ; break;//Zaxis; break;选择对应的x,y,z旋转角度来变化
case 'f':fd += 0.1; break;//Xdist; break;
case 's':fd -= 0.1; break;//Ydist; break;
case : // Escape Key
case 'q': case 'Q':
exit(EXIT_SUCCESS);
break;
}
if (fd == )fd = 0.1;
}
void SpecialKeys(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_UP:Dis += 0.01; break;
case GLUT_KEY_DOWN:Dis -= 0.01; break;//Ydist; break;
case GLUT_KEY_LEFT:Disx -= 0.01; break;
case GLUT_KEY_RIGHT:Disx += 0.01; break;//Xdist; break;
case : // Escape Key
case 'q': case 'Q':
exit(EXIT_SUCCESS);
break;
}
} //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void
idle(void)
{
Thet[Axi] += 0.01; if (Thet[Axi] > 360.0) {
Thet[Axi] -= 360.0;
}
glutSwapBuffers();
glutPostRedisplay();
} //---------------------------------------------------------------------------- int
main(int argc, char **argv)
{ glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(, );
glutInitContextVersion(, );
//这里在舍友的电脑上用3,2可以用,在我的电脑上会出现
//freeglut(dll地址):unableto create OpenGL3.2 context(flags 0, profile 1)
//我改成3,1就可以了。不知道会不会是版本问题。这里用的是比较旧的版本freeglut。 glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("Color Cube"); glewExperimental = true;
glewInit();
int nGlutColorMenu1 = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("black", );
glutAddMenuEntry("blue", );
glutAddMenuEntry("magenta", );
glutAddMenuEntry("cyan", ); int nGlutColorMenu2 = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("background1", );
glutAddMenuEntry("background2", );
glutAddMenuEntry("background3", );
glutAddMenuEntry("background4", );
glutAddMenuEntry("background5", ); int nGlutColorMenu3 = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("return", ); int nGlutColorMenu = glutCreateMenu(ProcessMenu);
glutAddSubMenu("coclor", nGlutColorMenu1);
glutAddSubMenu("background", nGlutColorMenu2);
glutAddSubMenu("return", nGlutColorMenu3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutDisplayFunc(display);
glutSpecialFunc(SpecialKeys);
glutKeyboardFunc(keyboard);
//glutMouseFunc(mouse);
glutIdleFunc(idle); glutMainLoop();
return ;
}
vshader.glsl
#version in vec2 vtexCoord;////新增或有更改
in vec4 vPosition;
in vec3 vNormal; out vec2 texCoord;////新增或有更改
out vec4 color; uniform vec4 AmbientProduct,DiffuseProduct,SpecularProduct;
uniform vec4 LightPosition;
uniform float Shininess;
uniform vec3 theta;
uniform float athat;
uniform float direct;
uniform float ff;
void main()
{
texCoord=vtexCoord;////新增或有更改
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles ); mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, s.x, 0.0,
0.0, -s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 ); mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 ); // Workaround for bug in ATI driver
ry[][] = 0.0;
ry[][] = 1.0; mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
-s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 ); // Workaround for bug in ATI driver
rz[][] = 1.0; //color = vColor;
mat4 t=mat4(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
athat,direct,0.0,1.0); mat4 sf=mat4(ff,0.0,,,
0.0,ff,0.0,0.0,
0.0,0.0,ff,0.0,
0.0,0.0,0.0,1.0);
mat4 modeview=t*rx*rz*ry;
vec3 pos=(modeview*vPosition).xyz; vec3 L=normalize(LightPosition.xyz-pos);
vec3 E=normalize(-pos);
vec3 H=normalize(L+E); vec3 N=normalize(modeview*vec4(vNormal,0.0)).xyz; vec4 ambient=AmbientProduct; float Kd=max(dot(L,N),0.0);
vec4 diffuse=Kd*DiffuseProduct;
float Ks=pow(max(dot(N,H),0.0),Shininess);
vec4 specular=Ks*SpecularProduct;
if(dot(L,N)<0.0) specular=vec4(0.0,0.0,0.0,1.0);
gl_Position =modeview*sf*vPosition;
color=ambient+diffuse+specular;
color.a=1.0;
}
fshader.glsl
#version
in vec2 texCoord;////新增或有更改
in vec4 color;
out vec4 fColor; uniform sampler2D texture;////新增或有更改
void main()
{ fColor = color*texture2D(texture,texCoord);////新增或有更改
}
InitShader.cpp
#include "Angel.h"
namespace Angel {
// Create a NULL-terminated string by reading the provided file
static char*
readShaderSource(const char* shaderFile)
{
//FILE* fp = fopen(shaderFile, "r");
//由于vs甚么安全性的原因,不让使用fopen,用下面的fopen_s代替;
FILE *fp;
fopen_s(&fp, shaderFile, "r");
if ( fp == NULL ) { return NULL; }
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char* buf = new char[size + ];
fread(buf, , size, fp);
buf[size] = '\0';
fclose(fp);
return buf;
}
// Create a GLSL program object from vertex and fragment shader files
GLuint
InitShader(const char* vShaderFile, const char* fShaderFile)
{
struct Shader {
const char* filename;
GLenum type;
GLchar* source;
} shaders[] = {
{ vShaderFile, GL_VERTEX_SHADER, NULL },
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
};
GLuint program = glCreateProgram();
for ( int i = ; i < ; ++i ) {
Shader& s = shaders[i];
s.source = readShaderSource( s.filename );
if ( shaders[i].source == NULL ) {
std::cerr << "Failed to read " << s.filename << std::endl;
exit( EXIT_FAILURE );
}
GLuint shader = glCreateShader( s.type );
glShaderSource( shader, , (const GLchar**) &s.source, NULL );
glCompileShader( shader );
GLint compiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled ) {
std::cerr << s.filename << " failed to compile:" << std::endl;
GLint logSize;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
char* logMsg = new char[logSize];
glGetShaderInfoLog( shader, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
delete [] s.source;
glAttachShader( program, shader );
}
/* link and error check */
glLinkProgram(program);
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
std::cerr << "Shader program failed to link" << std::endl;
GLint logSize;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog( program, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
/* use program object */
glUseProgram(program);
return program;
}
} // Close namespace Angel block

OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图的更多相关文章
- opencv 中affine函数实现旋转和平移
图像旋转和平移是图像处理中常用的一种操作,opencv2和opencv3中对图像的旋转和平移都是通过仿射变换函数cv::warpAffine()来实现的. 1.图像的旋转 图像的旋转具体实现分为两步: ...
- Android -- 图片处理, 画画板,缩放,旋转,平移,镜面,倒影,图片合成,颜色处理
1. 画画板 示例代码 public class MainActivity extends Activity { private ImageView iv; private Bitmap baseBi ...
- OpenGL ES 3D空间中自定义显示空间
在Android中,我们所熟知的是在ES管线中,其在图元装配时,会进行图元组装与图元分配,这样就回剪裁出来视景体中的物体.但是如果我想在3D场景中规定一个区域,凡是在这个区域中的物体就能显示出来,非这 ...
- OpenGl中使用着色器的基本步骤及GLSL渲染简单示例
OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...
- OpenGL管线(用经典管线代说着色器内部)
图形管线(graphics pipeline)向来以复杂为特点,这归结为图形任务的复杂性和挑战性.OpenGL作为图形硬件标准,是最通用的图形管线版本.本文用自顶向下的思路来简单总结OpenGL图形管 ...
- OpenGL ES着色器语言之着色概览(官方文档)
OpenGL ES着色器语言之着色概览(官方文档第二章) 事实上,OpenGL ES着色语言是两种紧密关联的语言.这些语言用来在OpenGL ES处理管线的可编程处理器创建着色器. 在本文档中,除非另 ...
- 2.x最终照着教程,成功使用OpenGL ES 绘制纹理贴图,添加了灰度图
在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理. 学校时候不知道OpenGL的重要性,怕晦涩的语法.没有跟老师学习OpenGL的环境配置,现在仅仅能利用coco ...
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...
- OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...
随机推荐
- ContextMenuOpening 事件
ContextMenuOpening事件,不能在将要触发的目标ContextMenu中触发,只能包含 这个ContextMenu的父控件中触发该事件. 在ListView中,希望控制右键弹出菜单时,可 ...
- HTML meta viewport属性说明
什么是Viewport 手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤 到很小的窗口中(这样会破坏没有针对手 ...
- 【Ubuntu12.04】安装搜狗输入法
我的系统版本是Ubuntu12.04 32位 卸载Ibus输入法 sudo apt-get remove ibus 注意: 安装ibus的命令是 sudo apt-get install fcitx ...
- 【算法】桶排->冒泡->快排
啊哈 算法 http://pan.baidu.com/s/1jGGl2SI http://pan.baidu.com/s/15C1oq 1 节 最快最简单的排序——桶排序 在我们生活的这个世界中到处都 ...
- CoreBluetooth - 中心模式
BLE中心模式流程-coding BLE中心模式流程 - 1.建立中心角色 - 2.扫描外设(Discover Peripheral) - 3.连接外设(Connect Peripheral) - 4 ...
- javascript 闭包暴露句柄和命名冲突的解决方案
暴露 最近在琢磨前端Js开源项目的东西,然后就一直好奇他们是怎么句柄暴露出来的,特整理一下两种方法. 将对象悬挂到window下面. 不使用var进行变量声明.下面上代码: (function(win ...
- Centos安装gnome主菜单编辑器无
首选项---主菜单-- 即是alacarte.. centos ===安装 alacarte.noarch 0:0.12.4-1.el6 即可.
- Hanoi
递归解决 汉诺塔 class Han{ int num; int steps; Han(int num){ this.num=num; } void total() { System.out.prin ...
- 基于协同过滤的个性化Web推荐
下面这是论文笔记,其实主要是摘抄,这片博士论文很有逻辑性,层层深入,所以笔者保留的比较多. 看到第二章,我发现其实这片文章对我来说更多是科普,科普吧…… 一.论文来源 Personalized Web ...
- A Neural Network in 11 lines of Python
A Neural Network in 11 lines of Python A bare bones neural network implementation to describe the in ...