首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将JavaScript/WebGL移植到Python/OpenGL

将JavaScript/WebGL移植到Python/OpenGL
EN

Stack Overflow用户
提问于 2018-11-27 19:47:16
回答 2查看 1.6K关注 0票数 1

我正在将节点/javascript中的一些WebGL代码移植到python3中的PyOpenGL代码中。尽管python代码确实打开了一个OpenGL窗口,但它不显示带有网格模式的矩形。为了排除故障,我已经将程序降到了最低限度,但是找不到问题。有什么想法吗?

下面是python代码,下面是原始javascript代码。

Python3:

代码语言:javascript
复制
import OpenGL
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GL.shaders import *
from OpenGL.GL.framebufferobjects import *
import numpy

class Viewport:
    base = None
    # Model object
    window=None
    windowsize=(256*3,144*3)

    def buildShader(self,txt, type):
        #print ("buildShader",txt,type)
        s = glCreateShader(type)
        glShaderSource(s, txt)
        glCompileShader(s)

        if (not glGetShaderiv(s, GL_COMPILE_STATUS)):
            raise RuntimeError ("Could not compile shader:" , glGetShaderInfoLog(s))
        return s

    def setUniforms(self,prog,modelvar,names):
        modelvar['uniform'] = {}
        for u in names:
            modelvar['uniform'][u] = glGetUniformLocation(prog, u)
        return modelvar

    def setAttribs(self,prog, modelvar,names):
        modelvar['attrib'] = {}
        for attrib in names:
            modelvar['attrib'][attrib]=glGetAttribLocation(prog,attrib)
        return modelvar

    def makeProgram(self,modelvar,vert, frag, uniforms, attribs):
        v = self.buildShader(vert, GL_VERTEX_SHADER)
        f = self.buildShader(frag, GL_FRAGMENT_SHADER)

        prog = glCreateProgram()
        glAttachShader(prog, v)
        glAttachShader(prog, f)
        glLinkProgram(prog)

        #if (not glGetProgramParameter(prog, GL_LINK_STATUS)):
        if (not glGetProgramiv(prog, GL_LINK_STATUS)):
            raise RuntimeError("Could not link program:" + glGetProgramInfoLog(prog))

        self.setUniforms(prog, modelvar, uniforms)
        self.setAttribs(prog, modelvar, attribs)

        return prog

    def makeBase(self):
        self.base = {}
        self.base['prog'] = self.makeProgram(
            self.base,
            open('base.vert').read(),
            open('base.frag').read(),
            ['view', 'zmin', 'aspect'], ['v'])

        self.base['vert'] = glGenBuffers(1) #createBuffer()
        glBindBuffer(GL_ARRAY_BUFFER, self.base['vert'])
        glBufferData(
            GL_ARRAY_BUFFER,
            numpy.array([-1, -1,
                        -1,  1,
                        1, -1,
                        1,  1],dtype=numpy.float32),
            GL_STATIC_DRAW)

        self.base['frac'] = 0.5
        return self.base

    def drawBase(self,base):
        glUseProgram(self.base['prog'])
        M=numpy.array([ 0.26 , 0.22 , 0.18 , 0, -0.4 , 0.13 , 0.11 , 0, 0 , 0.42 , -0.1 , 0, 0 , 0 , 0 , 1])
        glUniformMatrix4fv(self.base['uniform']['view'], 1, False, M)#self.viewMatrix())
        printer_aspectRatio=1.6
        glUniform1f(self.base['uniform']['aspect'], printer_aspectRatio)

        glBindBuffer(GL_ARRAY_BUFFER, self.base['vert'])
        glEnableVertexAttribArray(self.base['attrib']['v'])
        glVertexAttribPointer(self.base['attrib']['v'], 2, GL_FLOAT, False, 0, 0)

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)


    def draw(self):

        glClearColor(1, 1, 1, 1)
        glClear(GL_COLOR_BUFFER_BIT)
        self.drawBase(self.base)
        glutSwapBuffers()



    def __init__(self):

        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)

        glutInitWindowSize(self.windowsize[0],self.windowsize[1])    
        glutInitWindowPosition(0,0)    
        self.window=glutCreateWindow('hackathon-slicer')
        glutDisplayFunc(self.draw)

        glEnable(GL_DEPTH_TEST)

        self.base=self.makeBase()

        glutMainLoop()
        self.draw()

文件base.frag:

代码语言:javascript
复制
varying /*mediump*/ vec2 uv;

void main() {
   /*mediump*/ float u = mod(uv.x * 10.0, 1.0);
   /*mediump*/ float v = mod(uv.y * 10.0, 1.0);
   /*mediump*/ float t = (u > 0.1 && u < 0.9 &&
                   v > 0.1 && v < 0.9) ? 0.3 : 0.5;
   gl_FragColor = vec4(t, t, t, 1);
}

文件base.vert:

代码语言:javascript
复制
attribute vec2 v; // Vertex position

uniform mat4 view; // Model transform matrix
uniform /*mediump*/ float zmin; // Z position of plane
uniform /*mediump*/ float aspect; // Aspect ratio

varying /*mediump*/ vec2 uv;

void main() {
   gl_Position = view * vec4(v.x * aspect, v.y, zmin - 0.01, 1);
   gl_Position.w = (gl_Position.z + 1.0);
   uv = (vec2(v.x * aspect, v.y) + 1.0) / 2.0;
}

javascript代码使用相同的base.frag和vert文件,但是中间的单词不会被注释掉。

原始javascript代码:

代码语言:javascript
复制
'use strict';

let _ = require('underscore');
let glslify = require('glslify');

let ui = require('./ui.js');
let printer = require('./printer.js');

let canvas = document.getElementById("canvas");
let gl = canvas.getContext("experimental-webgl");

let base = makeBase();

function buildShader(txt, type){
    let s = gl.createShader(type);
    gl.shaderSource(s, txt);
    gl.compileShader(s);
    return s;
}

function setUniforms(prog, u){
    prog.uniform = {};
    _.each(u, function(u){ prog.uniform[u] = gl.getUniformLocation(prog, u); });
}

function setAttribs(prog, a){
    prog.attrib = {};
    _.each(a, function(a){ prog.attrib[a] = gl.getAttribLocation(prog, a); });
}

function makeProgram(vert, frag, uniforms, attribs){
    let v = buildShader(vert, gl.VERTEX_SHADER);
    let f = buildShader(frag, gl.FRAGMENT_SHADER);

    let prog = gl.createProgram();
    gl.attachShader(prog, v);
    gl.attachShader(prog, f);
    gl.linkProgram(prog);

    setUniforms(prog, uniforms);
    setAttribs(prog, attribs);

    return prog;
}

function makeBase(){
    let base = {};
    base.prog = makeProgram(
        glslify(__dirname + '/../shaders/base.vert'),
        glslify(__dirname + '/../shaders/base.frag'),
        ['view', 'zmin', 'aspect'], ['v']);

    base.vert = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, base.vert);
    gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array([-1, -1,
                          -1,  1,
                           1, -1,
                           1,  1]),
        gl.STATIC_DRAW);

    base.frac = 0.5;
    return base;
}


function drawBase(base){
    gl.useProgram(base.prog);
    let M=[ 0.26 , 0.22 , 0.18 , 0, -0.4 , 0.13 , 0.11 , 0, 0 , 0.42 , -0.1 , 0, 0 , 0 , 0 , 1];
    gl.uniformMatrix4fv(base.prog.uniform.view, false, M);
    gl.uniform1f(base.prog.uniform.aspect, printer.aspectRatio());

    gl.bindBuffer(gl.ARRAY_BUFFER, base.vert);
    gl.enableVertexAttribArray(base.prog.attrib.v);
    gl.vertexAttribPointer(base.prog.attrib.v, 2, gl.FLOAT, false, 0, 0);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}


function draw(){
    gl.clearColor(1, 1, 1, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    drawBase(base);
}

function init(){
    gl.enable(gl.DEPTH_TEST);
    draw();
}

module.exports = {'init': init};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-27 20:46:25

如果绑定了数组缓冲区,则将glVertexAttribPointer的第6个参数视为缓冲区对象的数据存储中的字节偏移量。但是参数的类型必须是指针。

在您的示例中,偏移量为0。这意味着,要么必须使用内置常量None

代码语言:javascript
复制
glVertexAttribPointer(self.base['attrib']['v'], 2, GL_FLOAT, False, 0, None)

或者您必须使用ctypes.cast,它将0转换为ctypes.c_void_p类型:

代码语言:javascript
复制
glVertexAttribPointer(self.base['attrib']['v'], 2, GL_FLOAT, False, 0,
    ctypes.cast(0, ctypes.c_void_p))

因为深度测试是由

代码语言:javascript
复制
glEnable(GL_DEPTH_TEST)

在每个帧的开头,您也必须清除深度缓冲区:

代码语言:javascript
复制
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
票数 1
EN

Stack Overflow用户

发布于 2018-11-28 16:23:21

我发现我确实需要在init中注释掉。我不明白原因,但它是有效的:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53507059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档