相同的代码,但在不同平台上产生不同的结果。

huangapple go评论75阅读模式
英文:

Same code but different results from different platform

问题

我明白你的请求,以下是翻译好的代码部分:

# cube.py文件中的一部分
class Cube(object):
    def __init__(self, vert_shader, frag_shader):
        self.vertices = np.array([
            # 在这里指定顶点坐标
            [-0.5, -0.5, -0.5],  # A 0
            [0.5, -0.5, -0.5],  # B 1
            [0.5, -0.5, 0.5],  # C 2
            [-0.5, -0.5, 0.5],  # D 3
            [-0.5, 0.5, -0.5],  # E 4
            [0.5, 0.5, -0.5],  # F 5
            [0.5, 0.5, 0.5],  # G 6
            [-0.5, 0.5, 0.5]  # H 7
        ], dtype=np.float32)

        self.indices = np.array([
            # 在这里指定索引
            4, 7, 5, 6,  # 顶部
            6, 0,
            0, 4, 1, 5, 2, 6, 3, 7, 0, 4,  # 侧面
            5, 1,
            0, 3, 1, 2  # 底部
        ])

        # 在这里使用坐标计算顶点法线
        normals = np.random.normal(0, 1, (self.vertices.shape[0], 3)).astype(np.float32)
        normals[:, 2] = np.abs(normals[:, 2])
        self.normals = normals / np.linalg.norm(normals, axis=1, keepdims=True)

        # 颜色:RGB格式
        self.colors = np.array([
            # 在这里指定顶点颜色
            [0.0, 0.0, 0.0],  # 黑色
            [1.0, 0.0, 0.0],  # 红色
            [1.0, 1.0, 0.0],  # 黄色
            [0.0, 1.0, 0.0],  # 绿色
            [0.0, 0.0, 1.0],  # 蓝色
            [1.0, 0.0, 1.0],  # 洋红色
            [1.0, 1.0, 1.0],  # 白色
            [0.0, 1.0, 1.0]  # 青色
        ], dtype=np.float32)

# libs/buffer.py文件中的一部分
class VAO(object):
    def __init__(self):
        self.vao = GL.glGenVertexArrays(1)
        GL.glBindVertexArray(self.vao)
        GL.glBindVertexArray(0)
        self.vbo = {}
        self.ebo = None

    def add_vbo(self, location, data, ncomponents=3, dtype=GL.GL_FLOAT, normalized=False, stride=0, offset=None):
        self.activate()
        buffer_idx = GL.glGenBuffers(1)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, buffer_idx)
        GL.glBufferData(GL.GL_ARRAY_BUFFER, data, GL.GL_STATIC_DRAW)
        GL.glVertexAttribPointer(location, ncomponents, dtype, normalized, stride, offset)
        GL.glEnableVertexAttribArray(location)
        self.vbo[location] = buffer_idx
        self.deactivate()

# viewer.py文件中的一部分
class Viewer:
    def __init__(self, width=800, height=800):
        self.fill_modes = cycle([GL.GL_LINE, GL.GL_POINT, GL.GL_FILL])
        # 窗口创建及其他初始化

    def run(self):
        while not glfw.window_should_close(self.win):
            # 清空绘制缓冲区
            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

            win_size = glfw.get_window_size(self.win)
            view = self.trackball.view_matrix()
            projection = self.trackball.projection_matrix(win_size)

            # 绘制场景对象
            for drawable in self.drawables:
                drawable.draw(projection, view, None)

            # 刷新绘制命令,交换绘制缓冲区
            glfw.swap_buffers(self.win)

            # 处理事件
            glfw.poll_events()

# 主程序和场景设置
def main():
    viewer = Viewer()
    # 放置基本对象的实例

    model = Cube("./gouraud.vert", "./gouraud.frag").setup()
    viewer.add(model)

    viewer.run()

if __name__ == '__main__':
    glfw.init()
    main()
    glfw.terminate()

希望这能帮助你解决冲突。

英文:

I have an exercise to draw a simple cube that teacher asks me to fill in where: <br> "YOUR CODE HERE ...". <br>
I have done it but when coming to see the result, it rendered something weird (Figure 1 ). I have run that code on my friend's laptop and it gave a really good cube (Figure 2). <br>
There are 3 files in used:

  • cube.py:
from libs.buffer import *
import glfw
class Cube(object):
def __init__(self, vert_shader, frag_shader):
self.vertices = np.array([
# YOUR CODE HERE to specify vertices&#39; coordinates
[-0.5, -0.5, -0.5],  # A 0
[0.5, -0.5, -0.5],  # B 1
[0.5, -0.5, 0.5],  # C 2
[-0.5, -0.5, 0.5],  # D 3
[-0.5, 0.5, -0.5],  # E 4
[0.5, 0.5, -0.5],  # F 5
[0.5, 0.5, 0.5],  # G 6
[-0.5, 0.5, 0.5]  # H 7
], dtype=np.float32)
self.indices = np.array([
# YOUR CODE HERE to specify indices
4, 7, 5, 6,  # Top
6, 0,
0, 4, 1, 5, 2, 6, 3, 7, 0, 4,  # Sides
5, 1,
0, 3, 1, 2  # Bottom
])
# YOUR CODE HERE to compute vertices&#39; normals using the coordinates
normals = np.random.normal(0, 1, (self.vertices.shape[0], 3)).astype(np.float32)
normals[:, 2] = np.abs(normals[:, 2])
self.normals = normals / np.linalg.norm(normals, axis=1, keepdims=True)
# colors: RGB format
self.colors = np.array([
# YOUR CODE HERE to specify vertices&#39; color
[0.0, 0.0, 0.0],  # black
[1.0, 0.0, 0.0],  # red
[1.0, 1.0, 0.0],  # yellow
[0.0, 1.0, 0.0],  # green
[0.0, 0.0, 1.0],  # blue
[1.0, 0.0, 1.0],  # magenta
[1.0, 1.0, 1.0],  # white
[0.0, 1.0, 1.0]  # cyan
], dtype=np.float32)
self.vao = VAO()
self.shader = Shader(vert_shader, frag_shader)
self.uma = UManager(self.shader)
#
&quot;&quot;&quot;
Create object -&gt; call setup -&gt; call draw
&quot;&quot;&quot;
def setup(self):
# setup VAO for drawing cylinder&#39;s side
self.vao.add_vbo(0, self.vertices, ncomponents=3, stride=0, offset=None)
self.vao.add_vbo(1, self.colors, ncomponents=3, stride=0, offset=None)
# setup EBO for drawing cylinder&#39;s side, bottom and top
self.vao.add_ebo(self.indices)
return self
def draw(self, projection, view, model):
GL.glUseProgram(self.shader.render_idx)
modelview = view
self.uma.upload_uniform_matrix4fv(projection, &#39;projection&#39;, True)
self.uma.upload_uniform_matrix4fv(modelview, &#39;modelview&#39;, True)
self.vao.activate()
GL.glDrawElements(GL.GL_TRIANGLE_STRIP, self.indices.shape[0], GL.GL_UNSIGNED_INT, None)
def key_handler(self, key):
if key == glfw.KEY_1:
self.selected_texture = 1
if key == glfw.KEY_2:
self.selected_texture = 2
  • libs/buffer.py:
import OpenGL.GL as GL
import cv2
class VAO(object):
def __init__(self):
self.vao = GL.glGenVertexArrays(1)
GL.glBindVertexArray(self.vao)
GL.glBindVertexArray(0)
self.vbo = {}
self.ebo = None
def add_vbo(self, location, data, ncomponents=3, dtype=GL.GL_FLOAT, normalized=False, stride=0, offset=None):
self.activate()
buffer_idx = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, buffer_idx)
GL.glBufferData(GL.GL_ARRAY_BUFFER, data, GL.GL_STATIC_DRAW)
# location = GL.glGetAttribLocation(self.shader.render_idx, name)
GL.glVertexAttribPointer(location, ncomponents, dtype, normalized, stride, offset)
GL.glEnableVertexAttribArray(location)
self.vbo[location] = buffer_idx
self.deactivate()
def add_ebo(self, indices):
self.activate()
self.ebo = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.ebo)
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW)
self.deactivate()
def __del__(self):
GL.glDeleteVertexArrays(1, [self.vao])
GL.glDeleteBuffers(1, list(self.vbo.values()))
if self.ebo is not None:
GL.glDeleteBuffers(1, [self.ebo])
def activate(self):
GL.glBindVertexArray(self.vao)  # activated
def deactivate(self):
GL.glBindVertexArray(0)  # activated
class UManager(object):
def __init__(self, shader):
self.shader = shader
self.textures = {}
@staticmethod
def load_texture(filename):
texture = cv2.cvtColor(cv2.imread(filename, 1), cv2.COLOR_BGR2RGB)
return texture
def _get_texture_loc(self):
if not bool(self.textures):
return 0
else:
locs = list(self.textures.keys())
locs.sort(reverse=True)
ret_id = locs[0] + 1
return ret_id
&quot;&quot;&quot;
* first call to setup_texture: activate GL.GL_TEXTURE0
&gt; use GL.glUniform1i to associate the activated texture to the texture in shading program (see fragment shader)
* second call to setup_texture: activate GL.GL_TEXTURE1
&gt; use GL.glUniform1i to associate the activated texture to the texture in shading program (see fragment shader)
* second call to setup_texture: activate GL.GL_TEXTURE2
&gt; use GL.glUniform1i to associate the activated texture to the texture in shading program (see fragment shader)
and so on
&quot;&quot;&quot;
def setup_texture(self, sampler_name, image_file):
rgb_image = UManager.load_texture(image_file)
GL.glUseProgram(self.shader.render_idx)  # must call before calling to GL.glUniform1i
texture_idx = GL.glGenTextures(1)
binding_loc = self._get_texture_loc()
self.textures[binding_loc] = {}
self.textures[binding_loc][&quot;id&quot;] = texture_idx
self.textures[binding_loc][&quot;name&quot;] = sampler_name
GL.glActiveTexture(GL.GL_TEXTURE0 + binding_loc)  # activate texture GL.GL_TEXTURE0, GL.GL_TEXTURE1, ...
GL.glBindTexture(GL.GL_TEXTURE_2D, texture_idx)
GL.glUniform1i(GL.glGetUniformLocation(self.shader.render_idx, sampler_name), binding_loc)
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB,
rgb_image.shape[1], rgb_image.shape[0], 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, rgb_image)
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
def upload_uniform_matrix4fv(self, matrix, name, transpose=True):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniformMatrix4fv(location, 1, transpose, matrix)
def upload_uniform_matrix3fv(self, matrix, name, transpose=False):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniformMatrix3fv(location, 1, transpose, matrix)
def upload_uniform_vector4fv(self, vector, name):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniform4fv(location, 1, vector)
def upload_uniform_vector3fv(self, vector, name):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniform3fv(location, 1, vector)
def upload_uniform_scalar1f(self, scalar, name):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniform1f(location, scalar)
def upload_uniform_scalar1i(self, scalar, name):
GL.glUseProgram(self.shader.render_idx)
location = GL.glGetUniformLocation(self.shader.render_idx, name)
GL.glUniform1i(location, scalar)
  • viewer.py (file to run):
import OpenGL.GL as GL              # standard Python OpenGL wrapper
import glfw                         # lean windows system wrapper for OpenGL
import numpy as np                  # all matrix manipulations &amp; OpenGL args
from itertools import cycle   # cyclic iterator to easily toggle polygon rendering modes
from libs.transform import Trackball
from cube import *
# ------------  Viewer class &amp; windows management ------------------------------
class Viewer:
&quot;&quot;&quot; GLFW viewer windows, with classic initialization &amp; graphics loop &quot;&quot;&quot;
def __init__(self, width=800, height=800):
self.fill_modes = cycle([GL.GL_LINE, GL.GL_POINT, GL.GL_FILL])
# version hints: create GL windows with &gt;= OpenGL 3.3 and core profile
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL.GL_TRUE)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.RESIZABLE, False)
glfw.window_hint(glfw.DEPTH_BITS, 16)
glfw.window_hint(glfw.DOUBLEBUFFER, True)
self.win = glfw.create_window(width, height, &#39;Viewer&#39;, None, None)
# make win&#39;s OpenGL context current; no OpenGL calls can happen before
glfw.make_context_current(self.win)
# initialize trackball
self.trackball = Trackball()
self.mouse = (0, 0)
# register event handlers
glfw.set_key_callback(self.win, self.on_key)
glfw.set_cursor_pos_callback(self.win, self.on_mouse_move)
glfw.set_scroll_callback(self.win, self.on_scroll)
# useful message to check OpenGL renderer characteristics
print(&#39;OpenGL&#39;, GL.glGetString(GL.GL_VERSION).decode() + &#39;, GLSL&#39;,
GL.glGetString(GL.GL_SHADING_LANGUAGE_VERSION).decode() +
&#39;, Renderer&#39;, GL.glGetString(GL.GL_RENDERER).decode())
# initialize GL by setting viewport and default render characteristics
GL.glClearColor(0.5, 0.5, 0.5, 0.1)
#GL.glEnable(GL.GL_CULL_FACE)   # enable backface culling (Exercise 1)
#GL.glFrontFace(GL.GL_CCW) # GL_CCW: default
GL.glEnable(GL.GL_DEPTH_TEST)  # enable depth test (Exercise 1)
GL.glDepthFunc(GL.GL_LESS)   # GL_LESS: default
# initially empty list of object to draw
self.drawables = []
def run(self):
&quot;&quot;&quot; Main render loop for this OpenGL windows &quot;&quot;&quot;
while not glfw.window_should_close(self.win):
# clear draw buffer
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
win_size = glfw.get_window_size(self.win)
view = self.trackball.view_matrix()
projection = self.trackball.projection_matrix(win_size)
# draw our scene objects
for drawable in self.drawables:
drawable.draw(projection, view, None)
# flush render commands, and swap draw buffers
glfw.swap_buffers(self.win)
# Poll for and process events
glfw.poll_events()
def add(self, *drawables):
&quot;&quot;&quot; add objects to draw in this windows &quot;&quot;&quot;
self.drawables.extend(drawables)
def on_key(self, _win, key, _scancode, action, _mods):
&quot;&quot;&quot; &#39;Q&#39; or &#39;Escape&#39; quits &quot;&quot;&quot;
if action == glfw.PRESS or action == glfw.REPEAT:
if key == glfw.KEY_ESCAPE or key == glfw.KEY_Q:
glfw.set_window_should_close(self.win, True)
if key == glfw.KEY_W:
GL.glPolygonMode(GL.GL_FRONT_AND_BACK, next(self.fill_modes))
for drawable in self.drawables:
if hasattr(drawable, &#39;key_handler&#39;):
drawable.key_handler(key)
def on_mouse_move(self, win, xpos, ypos):
&quot;&quot;&quot; Rotate on left-click &amp; drag, pan on right-click &amp; drag &quot;&quot;&quot;
old = self.mouse
self.mouse = (xpos, glfw.get_window_size(win)[1] - ypos)
if glfw.get_mouse_button(win, glfw.MOUSE_BUTTON_LEFT):
self.trackball.drag(old, self.mouse, glfw.get_window_size(win))
if glfw.get_mouse_button(win, glfw.MOUSE_BUTTON_RIGHT):
self.trackball.pan(old, self.mouse)
def on_scroll(self, win, _deltax, deltay):
&quot;&quot;&quot; Scroll controls the camera distance to trackball center &quot;&quot;&quot;
self.trackball.zoom(deltay, glfw.get_window_size(win)[1])
# -------------- main program and scene setup --------------------------------
def main():
&quot;&quot;&quot; create windows, add shaders &amp; scene objects, then run rendering loop &quot;&quot;&quot;
viewer = Viewer()
# place instances of our basic objects
model = Cube(&quot;./gouraud.vert&quot;, &quot;./gouraud.frag&quot;).setup()
viewer.add(model)
# start rendering loop
viewer.run()
if __name__ == &#39;__main__&#39;:
glfw.init()                # initialize windows system glfw
main()                     # main function keeps variables locally scoped
glfw.terminate()           # destroy all glfw windows and GL contexts

Hope someone can help me solve this conflict. <br>
P/s: I use MacOS whereas my friend uses Window.

答案1

得分: 0

问题在于<b>cube.py</b>中索引数组的数据类型。为了在各种操作系统上顺利运行,我们需要指定一个特定的数据类型。例如:self.indices = np.array([...], dtype=np.uint32)

英文:

The problem is the data type of index array in <b>cube.py</b>. We need to specify a specific type in order to run smoothly through various OSs. <br>
For example: self.indices = np.array([...], dtype=np.uint32).

huangapple
  • 本文由 发表于 2023年2月23日 20:41:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75544989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定